/* ELF executable support for BFD.
- Copyright (C) 1991-2020 Free Software Foundation, Inc.
+ Copyright (C) 1991-2021 Free Software Foundation, Inc.
Written by Fred Fish @ Cygnus Support, from information published
in "UNIX System V Release 4, Programmers Guide: ANSI C and
{
ufile_ptr filesize = bfd_get_file_size (abfd);
- if (filesize != 0 && dst->sh_size > filesize)
- _bfd_error_handler
- (_("warning: %pB has a corrupt section with a size (%"
- BFD_VMA_FMT "x) larger than the file size"),
- abfd, dst->sh_size);
+ if (filesize != 0
+ && ((ufile_ptr) dst->sh_offset > filesize
+ || dst->sh_size > filesize - dst->sh_offset))
+ {
+ abfd->read_only = 1;
+ _bfd_error_handler (_("warning: %pB has a section "
+ "extending past end of file"), abfd);
+ }
}
dst->sh_link = H_GET_32 (abfd, src->sh_link);
dst->sh_info = H_GET_32 (abfd, src->sh_info);
any side effects in ABFD, or any data it points to (like tdata), if the
file does not match the target vector. */
-const bfd_target *
+bfd_cleanup
elf_object_p (bfd *abfd)
{
Elf_External_Ehdr x_ehdr; /* Elf file header, external form */
/* If this is a relocatable file and there is no section header
table, then we're hosed. */
- if (i_ehdrp->e_shoff == 0 && i_ehdrp->e_type == ET_REL)
+ if (i_ehdrp->e_shoff < sizeof (x_ehdr) && i_ehdrp->e_type == ET_REL)
goto got_wrong_format_error;
/* As a simple sanity check, verify that what BFD thinks is the
goto got_wrong_format_error;
/* Further sanity check. */
- if (i_ehdrp->e_shoff == 0 && i_ehdrp->e_shnum != 0)
+ if (i_ehdrp->e_shoff < sizeof (x_ehdr) && i_ehdrp->e_shnum != 0)
goto got_wrong_format_error;
ebd = get_elf_backend_data (abfd);
&& ebd->elf_osabi != ELFOSABI_NONE)
goto got_wrong_format_error;
- if (i_ehdrp->e_shoff != 0)
+ if (i_ehdrp->e_shoff >= sizeof (x_ehdr))
{
file_ptr where = (file_ptr) i_ehdrp->e_shoff;
elf_elfsections (abfd) = (Elf_Internal_Shdr **) bfd_alloc (abfd, amt);
if (!elf_elfsections (abfd))
goto got_no_match;
+ elf_tdata (abfd)->being_created = bfd_zalloc (abfd, num_sec);
+ if (!elf_tdata (abfd)->being_created)
+ goto got_no_match;
memcpy (i_shdrp, &i_shdr, sizeof (*i_shdrp));
for (shdrp = i_shdrp, shindex = 0; shindex < num_sec; shindex++)
So we are kind, and reset the string index value to 0
so that at least some processing can be done. */
i_ehdrp->e_shstrndx = SHN_UNDEF;
+ abfd->read_only = 1;
_bfd_error_handler
(_("warning: %pB has a corrupt string table index - ignoring"),
abfd);
if (bfd_bread (&x_phdr, sizeof x_phdr, abfd) != sizeof x_phdr)
goto got_no_match;
elf_swap_phdr_in (abfd, &x_phdr, i_phdr);
+ /* Too much code in BFD relies on alignment being a power of
+ two, as required by the ELF spec. */
+ if (i_phdr->p_align != (i_phdr->p_align & -i_phdr->p_align))
+ {
+ abfd->read_only = 1;
+ _bfd_error_handler (_("warning: %pB has a program header "
+ "with invalid alignment"), abfd);
+ }
}
}
- if (i_ehdrp->e_shstrndx != 0 && i_ehdrp->e_shoff != 0)
+ if (i_ehdrp->e_shstrndx != 0 && i_ehdrp->e_shoff >= sizeof (x_ehdr))
{
unsigned int num_sec;
s->flags |= SEC_DEBUGGING;
}
}
- return target;
+ return _bfd_no_cleanup;
got_wrong_format_error:
bfd_set_error (bfd_error_wrong_format);
void
elf_write_relocs (bfd *abfd, asection *sec, void *data)
{
+ const struct elf_backend_data * const bed = get_elf_backend_data (abfd);
bfd_boolean *failedp = (bfd_boolean *) data;
Elf_Internal_Shdr *rela_hdr;
bfd_vma addr_offset;
src_rela.r_addend = ptr->addend;
(*swap_out) (abfd, &src_rela, dst_rela);
}
+
+ if (elf_section_data (sec)->has_secondary_relocs
+ && !bed->write_secondary_relocs (abfd, sec))
+ {
+ *failedp = TRUE;
+ return;
+ }
}
/* Write out the program headers. */
if (contents != NULL)
{
(*process) (contents, i_shdr.sh_size, arg);
- if (free_contents != NULL)
- free (free_contents);
+ free (free_contents);
}
}
{
/* This symbol is in a section for which we did not
create a BFD section. Just use bfd_abs_section,
- although it is wrong. FIXME. */
+ although it is wrong. FIXME. Note - there is
+ code in elf.c:swap_out_syms that calls
+ symbol_section_index() in the elf backend for
+ cases like this. */
sym->symbol.section = bfd_abs_section_ptr;
}
}
*symptrs = 0; /* Final null pointer */
}
- if (xverbuf != NULL)
- free (xverbuf);
- if (isymbuf != NULL && hdr->contents != (unsigned char *) isymbuf)
+ free (xverbuf);
+ if (hdr->contents != (unsigned char *) isymbuf)
free (isymbuf);
return symcount;
error_return:
- if (xverbuf != NULL)
- free (xverbuf);
- if (isymbuf != NULL && hdr->contents != (unsigned char *) isymbuf)
+ free (xverbuf);
+ if (hdr->contents != (unsigned char *) isymbuf)
free (isymbuf);
return -1;
}
goto error_return;
}
- if (allocated != NULL)
- free (allocated);
+ free (allocated);
return TRUE;
error_return:
- if (allocated != NULL)
- free (allocated);
+ free (allocated);
return FALSE;
}
asymbol **symbols,
bfd_boolean dynamic)
{
+ const struct elf_backend_data * const bed = get_elf_backend_data (abfd);
struct bfd_elf_section_data * const d = elf_section_data (asect);
Elf_Internal_Shdr *rel_hdr;
Elf_Internal_Shdr *rel_hdr2;
symbols, dynamic))
return FALSE;
+ if (!bed->slurp_secondary_relocs (abfd, asect, symbols, dynamic))
+ return FALSE;
+
asect->relocation = relents;
return TRUE;
}
bfd *
NAME(_bfd_elf,bfd_from_remote_memory)
(bfd *templ,
- bfd_vma ehdr_vma,
- bfd_size_type size,
- bfd_vma *loadbasep,
+ bfd_vma ehdr_vma /* Bytes. */,
+ bfd_size_type size /* Octets. */,
+ bfd_vma *loadbasep /* Bytes. */,
int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type))
+ /* (Bytes , , octets ). */
{
Elf_External_Ehdr x_ehdr; /* Elf file header, external form */
Elf_Internal_Ehdr i_ehdr; /* Elf file header, internal form */
unsigned int i;
bfd_vma high_offset;
bfd_vma shdr_end;
- bfd_vma loadbase;
- char *filename;
+ bfd_vma loadbase; /* Bytes. */
size_t amt;
+ unsigned int opb = bfd_octets_per_byte (templ, NULL);
/* Read in the ELF header in external format. */
err = target_read_memory (ehdr_vma, (bfd_byte *) &x_ehdr, sizeof x_ehdr);
header sits, then we can figure out the loadbase. */
if (first_phdr == NULL)
{
- bfd_vma p_offset = i_phdrs[i].p_offset;
- bfd_vma p_vaddr = i_phdrs[i].p_vaddr;
+ bfd_vma p_offset = i_phdrs[i].p_offset; /* Octets. */
+ bfd_vma p_vaddr = i_phdrs[i].p_vaddr; /* Octets. */
if (i_phdrs[i].p_align > 1)
{
- p_offset &= -i_phdrs[i].p_align;
- p_vaddr &= -i_phdrs[i].p_align;
+ p_offset &= -(i_phdrs[i].p_align * opb);
+ p_vaddr &= -(i_phdrs[i].p_align * opb);
}
if (p_offset == 0)
{
- loadbase = ehdr_vma - p_vaddr;
+ loadbase = ehdr_vma - p_vaddr / opb;
first_phdr = &i_phdrs[i];
}
}
for (i = 0; i < i_ehdr.e_phnum; ++i)
if (i_phdrs[i].p_type == PT_LOAD)
{
- bfd_vma start = i_phdrs[i].p_offset;
- bfd_vma end = start + i_phdrs[i].p_filesz;
- bfd_vma vaddr = i_phdrs[i].p_vaddr;
+ bfd_vma start = i_phdrs[i].p_offset; /* Octets. */
+ bfd_vma end = start + i_phdrs[i].p_filesz; /* Octets. */
+ bfd_vma vaddr = i_phdrs[i].p_vaddr; /* Octets. */
/* Extend the beginning of the first pt_load to cover file
header and program headers, if we proved earlier that its
/* Extend the end of the last pt_load to cover section headers. */
if (last_phdr == &i_phdrs[i])
end = high_offset;
- err = target_read_memory (loadbase + vaddr,
+ err = target_read_memory (loadbase + vaddr / opb,
contents + start, end - start);
if (err)
{
free (contents);
return NULL;
}
- filename = bfd_strdup ("<in-memory>");
- if (filename == NULL)
- {
- free (bim);
- free (contents);
- return NULL;
- }
nbfd = _bfd_new_bfd ();
- if (nbfd == NULL)
+ if (nbfd == NULL
+ || !bfd_set_filename (nbfd, "<in-memory>"))
{
- free (filename);
free (bim);
free (contents);
return NULL;
}
- nbfd->filename = filename;
nbfd->xvec = templ->xvec;
bim->size = high_offset;
bim->buffer = contents;