/* Allocate and clear an extra byte at the end, to prevent crashes
in case the string table is not terminated. */
if (shstrtabsize + 1 <= 1
+ || shstrtabsize > bfd_get_file_size (abfd)
|| bfd_seek (abfd, offset, SEEK_SET) != 0
|| (shstrtab = (bfd_byte *) bfd_alloc (abfd, shstrtabsize + 1)) == NULL)
shstrtab = NULL;
bfd_alloc2 (abfd, num_group, sizeof (Elf_Internal_Shdr *));
if (elf_tdata (abfd)->group_sect_ptr == NULL)
return FALSE;
- memset (elf_tdata (abfd)->group_sect_ptr, 0, num_group * sizeof (Elf_Internal_Shdr *));
+ memset (elf_tdata (abfd)->group_sect_ptr, 0,
+ num_group * sizeof (Elf_Internal_Shdr *));
num_group = 0;
for (i = 0; i < shnum; i++)
|= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
break;
}
- if (idx >= shnum)
+ if (idx < shnum)
+ dest->shdr = elf_elfsections (abfd)[idx];
+ if (idx >= shnum
+ || dest->shdr->sh_type == SHT_GROUP)
{
_bfd_error_handler
- (_("%pB: invalid SHT_GROUP entry"), abfd);
- idx = 0;
+ (_("%pB: invalid entry in SHT_GROUP section [%u]"),
+ abfd, i);
+ dest->shdr = NULL;
}
- dest->shdr = elf_elfsections (abfd)[idx];
}
}
}
idx = (Elf_Internal_Group *) shdr->contents;
n_elt = shdr->sh_size / 4;
while (--n_elt != 0)
- if ((s = (++idx)->shdr->bfd_section) != NULL
+ if ((++idx)->shdr != NULL
+ && (s = idx->shdr->bfd_section) != NULL
&& elf_next_in_group (s) != NULL)
break;
if (n_elt != 0)
{
_bfd_error_handler
/* xgettext:c-format */
- (_("%pB: Invalid sh_link field (%d) in section number %d"),
+ (_("%pB: invalid sh_link field (%d) in section number %d"),
ibfd, iheader->sh_link, secnum);
return FALSE;
}
if we could not find a match ? */
_bfd_error_handler
/* xgettext:c-format */
- (_("%pB: Failed to find link section for section %d"), obfd, secnum);
+ (_("%pB: failed to find link section for section %d"), obfd, secnum);
}
if (iheader->sh_info)
else
_bfd_error_handler
/* xgettext:c-format */
- (_("%pB: Failed to find info section for section %d"), obfd, secnum);
+ (_("%pB: failed to find info section for section %d"), obfd, secnum);
}
return changed;
{
_bfd_error_handler
/* xgettext:c-format */
- (_("%pB: error: Alignment power %d of section `%pA' is too big"),
+ (_("%pB: error: alignment power %d of section `%pA' is too big"),
abfd, asect->alignment_power, asect);
arg->failed = TRUE;
return;
{
elf_symbol_type *type_ptr;
+ if (sym == NULL)
+ return FALSE;
+
if ((sym->flags & BSF_SECTION_SYM) == 0)
return FALSE;
+ if (sym->section == NULL)
+ return TRUE;
+
type_ptr = elf_symbol_from (abfd, sym);
return ((type_ptr != NULL
&& type_ptr->internal_elf_sym.st_shndx != 0
&& bfd_is_abs_section (sym->section))
|| !(sym->section->owner == abfd
- || (sym->section->output_section->owner == abfd
+ || (sym->section->output_section != NULL
+ && sym->section->output_section->owner == abfd
&& sym->section->output_offset == 0)
|| bfd_is_abs_section (sym->section)));
}
&& p->p_paddr < (bfd_vma) off))
{
_bfd_error_handler
- (_("%pB: Not enough room for program headers,"
+ (_("%pB: not enough room for program headers,"
" try linking with -N"),
abfd);
bfd_set_error (bfd_error_bad_value);
}
/* 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. */
+ alloc = elf_elfheader (abfd)->e_phnum;
if (alloc == 0)
return TRUE;
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)))
+ || (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 (_("\
-%pB: error: PHDR segment not covered by LOAD segment"),
+ _bfd_error_handler (_("%pB: error: PHDR segment not covered"
+ " by LOAD segment"),
abfd);
return FALSE;
}
: segment->p_vaddr != section->vma) \
|| (strcmp (bfd_get_section_name (ibfd, section), ".dynamic") \
== 0)) \
- && !section->segment_mark)
+ && (segment->p_type != PT_LOAD || !section->segment_mark))
/* If the output section of a section in the input segment is NULL,
it is removed from the corresponding output segment. */
asection **sections;
asection *output_section;
unsigned int isec;
- bfd_vma matching_lma;
- bfd_vma suggested_lma;
+ asection *matching_lma;
+ asection *suggested_lma;
unsigned int j;
bfd_size_type amt;
asection *first_section;
- bfd_boolean first_matching_lma;
- bfd_boolean first_suggested_lma;
if (segment->p_type == PT_NULL)
continue;
if (segment->p_type == PT_LOAD
&& (segment->p_filesz > 0 || segment->p_memsz == 0))
/* xgettext:c-format */
- _bfd_error_handler (_("%pB: warning: Empty loadable segment detected"
- " at vaddr=%#" PRIx64 ", is this intentional?"),
- ibfd, (uint64_t) segment->p_vaddr);
+ _bfd_error_handler
+ (_("%pB: warning: empty loadable segment detected"
+ " at vaddr=%#" PRIx64 ", is this intentional?"),
+ ibfd, (uint64_t) segment->p_vaddr);
map->count = 0;
*pointer_to_map = map;
we have completely filled the segment, and there is nothing
more to do. */
isec = 0;
- matching_lma = 0;
- suggested_lma = 0;
- first_matching_lma = TRUE;
- first_suggested_lma = TRUE;
+ matching_lma = NULL;
+ suggested_lma = NULL;
for (section = first_section, j = 0;
section != NULL;
&& !bed->want_p_paddr_set_to_zero
&& isec == 0
&& output_section->lma != 0
- && output_section->vma == (segment->p_vaddr
- + (map->includes_filehdr
- ? iehdr->e_ehsize
- : 0)
- + (map->includes_phdrs
- ? (iehdr->e_phnum
- * iehdr->e_phentsize)
- : 0)))
+ && (align_power (segment->p_vaddr
+ + (map->includes_filehdr
+ ? iehdr->e_ehsize : 0)
+ + (map->includes_phdrs
+ ? iehdr->e_phnum * iehdr->e_phentsize
+ : 0),
+ output_section->alignment_power)
+ == output_section->vma))
map->p_paddr = segment->p_vaddr;
/* Match up the physical address of the segment with the
|| (bed->want_p_paddr_set_to_zero
&& IS_CONTAINED_BY_VMA (output_section, segment)))
{
- if (first_matching_lma || output_section->lma < matching_lma)
- {
- matching_lma = output_section->lma;
- first_matching_lma = FALSE;
- }
+ if (matching_lma == NULL
+ || output_section->lma < matching_lma->lma)
+ matching_lma = output_section;
/* We assume that if the section fits within the segment
then it does not overlap any other section within that
segment. */
map->sections[isec++] = output_section;
}
- else if (first_suggested_lma)
- {
- suggested_lma = output_section->lma;
- first_suggested_lma = FALSE;
- }
+ else if (suggested_lma == NULL)
+ suggested_lma = output_section;
if (j == section_count)
break;
if (p_paddr_valid
&& !bed->want_p_paddr_set_to_zero
- && matching_lma != map->p_paddr
+ && matching_lma->lma != map->p_paddr
&& !map->includes_filehdr
&& !map->includes_phdrs)
/* There is some padding before the first section in the
segment. So, we must account for that in the output
segment's vma. */
- map->p_vaddr_offset = matching_lma - map->p_paddr;
+ map->p_vaddr_offset = matching_lma->lma - map->p_paddr;
free (sections);
continue;
}
else
{
- if (!first_matching_lma)
- {
- /* At least one section fits inside the current segment.
- Keep it, but modify its physical address to match the
- LMA of the first section that fitted. */
- map->p_paddr = matching_lma;
- }
- else
- {
- /* None of the sections fitted inside the current segment.
- Change the current segment's physical address to match
- the LMA of the first section. */
- map->p_paddr = suggested_lma;
- }
+ /* Change the current segment's physical address to match
+ the LMA of the first section that fitted, or if no
+ section fitted, the first section. */
+ if (matching_lma == NULL)
+ matching_lma = suggested_lma;
+
+ map->p_paddr = matching_lma->lma;
/* Offset the segment physical address from the lma
to allow for space taken up by elf headers. */
- if (map->includes_filehdr)
+ if (map->includes_phdrs)
{
- if (map->p_paddr >= iehdr->e_ehsize)
- map->p_paddr -= iehdr->e_ehsize;
- else
- {
- map->includes_filehdr = FALSE;
- map->includes_phdrs = FALSE;
- }
+ map->p_paddr -= iehdr->e_phnum * iehdr->e_phentsize;
+
+ /* iehdr->e_phnum is just an estimate of the number
+ of program headers that we will need. Make a note
+ here of the number we used and the segment we chose
+ to hold these headers, so that we can adjust the
+ offset when we know the correct value. */
+ phdr_adjust_num = iehdr->e_phnum;
+ phdr_adjust_seg = map;
}
- if (map->includes_phdrs)
+ if (map->includes_filehdr)
{
- if (map->p_paddr >= iehdr->e_phnum * iehdr->e_phentsize)
- {
- map->p_paddr -= iehdr->e_phnum * iehdr->e_phentsize;
-
- /* iehdr->e_phnum is just an estimate of the number
- of program headers that we will need. Make a note
- here of the number we used and the segment we chose
- to hold these headers, so that we can adjust the
- offset when we know the correct value. */
- phdr_adjust_num = iehdr->e_phnum;
- phdr_adjust_seg = map;
- }
- else
- map->includes_phdrs = FALSE;
+ bfd_vma align = (bfd_vma) 1 << matching_lma->alignment_power;
+ map->p_paddr -= iehdr->e_ehsize;
+ /* We've subtracted off the size of headers from the
+ first section lma, but there may have been some
+ alignment padding before that section too. Try to
+ account for that by adjusting the segment lma down to
+ the same alignment. */
+ if (segment->p_align != 0 && segment->p_align < align)
+ align = segment->p_align;
+ map->p_paddr &= -align;
}
}
do
{
map->count = 0;
- suggested_lma = 0;
- first_suggested_lma = TRUE;
+ suggested_lma = NULL;
/* Fill the current segment with sections that fit. */
for (j = 0; j < section_count; j++)
/* If the first section in a segment does not start at
the beginning of the segment, then something is
wrong. */
- if (output_section->lma
- != (map->p_paddr
- + (map->includes_filehdr ? iehdr->e_ehsize : 0)
- + (map->includes_phdrs
- ? iehdr->e_phnum * iehdr->e_phentsize
- : 0)))
+ if (align_power (map->p_paddr
+ + (map->includes_filehdr
+ ? iehdr->e_ehsize : 0)
+ + (map->includes_phdrs
+ ? iehdr->e_phnum * iehdr->e_phentsize
+ : 0),
+ output_section->alignment_power)
+ != output_section->lma)
abort ();
}
else
|| (prev_sec->lma + prev_sec->size
> output_section->lma))
{
- if (first_suggested_lma)
- {
- suggested_lma = output_section->lma;
- first_suggested_lma = FALSE;
- }
+ if (suggested_lma == NULL)
+ suggested_lma = output_section;
continue;
}
map->sections[map->count++] = output_section;
++isec;
sections[j] = NULL;
- section->segment_mark = TRUE;
- }
- else if (first_suggested_lma)
- {
- suggested_lma = output_section->lma;
- first_suggested_lma = FALSE;
+ if (segment->p_type == PT_LOAD)
+ section->segment_mark = TRUE;
}
+ else if (suggested_lma == NULL)
+ suggested_lma = output_section;
}
BFD_ASSERT (map->count > 0);
map->p_type = segment->p_type;
map->p_flags = segment->p_flags;
map->p_flags_valid = 1;
- map->p_paddr = suggested_lma;
+ map->p_paddr = suggested_lma->lma;
map->p_paddr_valid = p_paddr_valid;
map->includes_filehdr = 0;
map->includes_phdrs = 0;
if (count > phdr_adjust_num)
phdr_adjust_seg->p_paddr
-= (count - phdr_adjust_num) * iehdr->e_phentsize;
+
+ for (map = map_first; map != NULL; map = map->next)
+ if (map->p_type == PT_PHDR)
+ {
+ bfd_vma adjust
+ = phdr_adjust_seg->includes_filehdr ? iehdr->e_ehsize : 0;
+ map->p_paddr = phdr_adjust_seg->p_paddr + adjust;
+ break;
+ }
}
#undef SEGMENT_END
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>",
- sec->name);
+ _bfd_error_handler
+ (_("unable to find equivalent output section"
+ " for symbol '%s' from section '%s'"),
+ syms[idx]->name ? syms[idx]->name : "<Local sym>",
+ sec->name);
bfd_set_error (bfd_error_invalid_operation);
goto error_return;
}
return TRUE;
}
-void
+bfd_boolean
_bfd_elf_no_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
arelent *cache_ptr ATTRIBUTE_UNUSED,
Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
{
abort ();
+ return FALSE;
}
/* Try to convert a non-ELF reloc into an ELF one. */
return TRUE;
fail:
- _bfd_error_handler
- /* xgettext:c-format */
- (_("%pB: unsupported relocation type %s"),
- abfd, areloc->howto->name);
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%pB: %s unsupported"),
+ abfd, areloc->howto->name);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
return buf;
}
+/* gcc-8 warns (*) on all the strncpy calls in this function about
+ possible string truncation. The "truncation" is not a bug. We
+ have an external representation of structs with fields that are not
+ necessarily NULL terminated and corresponding internal
+ representation fields that are one larger so that they can always
+ be NULL terminated.
+ gcc versions between 4.2 and 4.6 do not allow pragma control of
+ diagnostics inside functions, giving a hard error if you try to use
+ the finer control available with later versions.
+ gcc prior to 4.2 warns about diagnostic push and pop.
+ gcc-5, gcc-6 and gcc-7 warn that -Wstringop-truncation is unknown,
+ unless you also add #pragma GCC diagnostic ignored "-Wpragma".
+ (*) Depending on your system header files! */
+#if GCC_VERSION >= 8000
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wstringop-truncation"
+#endif
char *
elfcore_write_prpsinfo (bfd *abfd,
char *buf,
}
#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
-#if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T)
+# if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T)
if (bed->s->elfclass == ELFCLASS32)
{
-#if defined (HAVE_PSINFO32_T)
+# if defined (HAVE_PSINFO32_T)
psinfo32_t data;
int note_type = NT_PSINFO;
-#else
+# else
prpsinfo32_t data;
int note_type = NT_PRPSINFO;
-#endif
+# endif
memset (&data, 0, sizeof (data));
strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
"CORE", note_type, &data, sizeof (data));
}
else
-#endif
+# endif
{
-#if defined (HAVE_PSINFO_T)
+# if defined (HAVE_PSINFO_T)
psinfo_t data;
int note_type = NT_PSINFO;
-#else
+# else
prpsinfo_t data;
int note_type = NT_PRPSINFO;
-#endif
+# endif
memset (&data, 0, sizeof (data));
strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
free (buf);
return NULL;
}
+#if GCC_VERSION >= 8000
+# pragma GCC diagnostic pop
+#endif
char *
elfcore_write_linux_prpsinfo32