Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 5197 → Rev 6324

/contrib/toolchain/binutils/bfd/elfcode.h
1,7 → 1,5
/* ELF executable support for BFD.
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
Copyright (C) 1991-2015 Free Software Foundation, Inc.
 
Written by Fred Fish @ Cygnus Support, from information published
in "UNIX System V Release 4, Programmers Guide: ANSI C and
73,6 → 71,7
#include "bfdlink.h"
#include "libbfd.h"
#include "elf-bfd.h"
#include "libiberty.h"
 
/* Renaming structures, typedefs, macros and functions to be size-specific. */
#define Elf_External_Ehdr NAME(Elf,External_Ehdr)
606,13 → 605,10
 
if (i_ehdrp->e_shoff != 0)
{
bfd_signed_vma where = i_ehdrp->e_shoff;
file_ptr where = (file_ptr) i_ehdrp->e_shoff;
 
if (where != (file_ptr) where)
goto got_wrong_format_error;
 
/* Seek to the section header table in the file. */
if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0)
if (bfd_seek (abfd, where, SEEK_SET) != 0)
goto got_no_match;
 
/* Read the first section header at index 0, and convert to internal
658,12 → 654,10
goto got_wrong_format_error;
 
where += (i_ehdrp->e_shnum - 1) * sizeof (x_shdr);
if (where != (file_ptr) where)
goto got_wrong_format_error;
if ((bfd_size_type) where <= i_ehdrp->e_shoff)
goto got_wrong_format_error;
 
if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0)
if (bfd_seek (abfd, where, SEEK_SET) != 0)
goto got_no_match;
if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr))
goto got_no_match;
670,7 → 664,7
 
/* Back to where we were. */
where = i_ehdrp->e_shoff + sizeof (x_shdr);
if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0)
if (bfd_seek (abfd, where, SEEK_SET) != 0)
goto got_no_match;
}
}
682,6 → 676,10
Elf_Internal_Shdr *shdrp;
unsigned int num_sec;
 
#ifndef BFD64
if (i_ehdrp->e_shnum > ((bfd_size_type) -1) / sizeof (*i_shdrp))
goto got_wrong_format_error;
#endif
amt = sizeof (*i_shdrp) * i_ehdrp->e_shnum;
i_shdrp = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt);
if (!i_shdrp)
713,7 → 711,7
switch (ebd->elf_machine_code)
{
case EM_386:
case EM_486:
case EM_IAMCU:
case EM_X86_64:
case EM_OLD_SPARCV9:
case EM_SPARC32PLUS:
772,7 → 770,11
Elf_Internal_Phdr *i_phdr;
unsigned int i;
 
amt = i_ehdrp->e_phnum * sizeof (Elf_Internal_Phdr);
#ifndef BFD64
if (i_ehdrp->e_phnum > ((bfd_size_type) -1) / sizeof (*i_phdr))
goto got_wrong_format_error;
#endif
amt = i_ehdrp->e_phnum * sizeof (*i_phdr);
elf_tdata (abfd)->phdr = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt);
if (elf_tdata (abfd)->phdr == NULL)
goto got_no_match;
1215,10 → 1217,9
for (isym = isymbuf + 1, sym = symbase; isym < isymend; isym++, sym++)
{
memcpy (&sym->internal_elf_sym, isym, sizeof (Elf_Internal_Sym));
 
sym->symbol.the_bfd = abfd;
 
sym->symbol.name = bfd_elf_sym_name (abfd, hdr, isym, NULL);
 
sym->symbol.value = isym->st_value;
 
if (isym->st_shndx == SHN_UNDEF)
1502,7 → 1503,9
rel_hdr2 = d->rela.hdr;
reloc_count2 = rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0;
 
BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2);
/* PR 17512: file: 0b4f81b7. */
if (asect->reloc_count != reloc_count + reloc_count2)
return FALSE;
BFD_ASSERT ((rel_hdr && asect->rel_filepos == rel_hdr->sh_offset)
|| (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
 
1588,22 → 1591,25
#endif
/* Create a new BFD as if by bfd_openr. Rather than opening a file,
reconstruct an ELF file by reading the segments out of remote memory
based on the ELF file header at EHDR_VMA and the ELF program headers it
points to. If not null, *LOADBASEP is filled in with the difference
between the VMAs from which the segments were read, and the VMAs the
file headers (and hence BFD's idea of each section's VMA) put them at.
reconstruct an ELF file by reading the segments out of remote
memory based on the ELF file header at EHDR_VMA and the ELF program
headers it points to. If non-zero, SIZE is the known extent of the
object. If not null, *LOADBASEP is filled in with the difference
between the VMAs from which the segments were read, and the VMAs
the file headers (and hence BFD's idea of each section's VMA) put
them at.
 
The function TARGET_READ_MEMORY is called to copy LEN bytes from the
remote memory at target address VMA into the local buffer at MYADDR; it
should return zero on success or an `errno' code on failure. TEMPL must
be a BFD for a target with the word size and byte order found in the
remote memory. */
The function TARGET_READ_MEMORY is called to copy LEN bytes from
the remote memory at target address VMA into the local buffer at
MYADDR; it should return zero on success or an `errno' code on
failure. TEMPL must be a BFD for a target with the word size and
byte order found in the remote memory. */
 
bfd *
NAME(_bfd_elf,bfd_from_remote_memory)
(bfd *templ,
bfd_vma ehdr_vma,
bfd_size_type size,
bfd_vma *loadbasep,
int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type))
{
1610,15 → 1616,15
Elf_External_Ehdr x_ehdr; /* Elf file header, external form */
Elf_Internal_Ehdr i_ehdr; /* Elf file header, internal form */
Elf_External_Phdr *x_phdrs;
Elf_Internal_Phdr *i_phdrs, *last_phdr;
Elf_Internal_Phdr *i_phdrs, *last_phdr, *first_phdr;
bfd *nbfd;
struct bfd_in_memory *bim;
int contents_size;
bfd_byte *contents;
int err;
unsigned int i;
bfd_vma high_offset;
bfd_vma shdr_end;
bfd_vma loadbase;
bfd_boolean loadbase_set;
 
/* Read in the ELF header in external format. */
err = target_read_memory (ehdr_vma, (bfd_byte *) &x_ehdr, sizeof x_ehdr);
1678,10 → 1684,7
x_phdrs = (Elf_External_Phdr *)
bfd_malloc (i_ehdr.e_phnum * (sizeof *x_phdrs + sizeof *i_phdrs));
if (x_phdrs == NULL)
{
bfd_set_error (bfd_error_no_memory);
return NULL;
}
err = target_read_memory (ehdr_vma + i_ehdr.e_phoff, (bfd_byte *) x_phdrs,
i_ehdr.e_phnum * sizeof x_phdrs[0]);
if (err)
1693,34 → 1696,44
}
i_phdrs = (Elf_Internal_Phdr *) &x_phdrs[i_ehdr.e_phnum];
 
contents_size = 0;
high_offset = 0;
loadbase = 0;
first_phdr = NULL;
last_phdr = NULL;
loadbase = ehdr_vma;
loadbase_set = FALSE;
for (i = 0; i < i_ehdr.e_phnum; ++i)
{
elf_swap_phdr_in (templ, &x_phdrs[i], &i_phdrs[i]);
if (i_phdrs[i].p_type == PT_LOAD)
{
bfd_vma segment_end;
segment_end = (i_phdrs[i].p_offset + i_phdrs[i].p_filesz
+ i_phdrs[i].p_align - 1) & -i_phdrs[i].p_align;
if (segment_end > (bfd_vma) contents_size)
contents_size = segment_end;
bfd_vma segment_end = i_phdrs[i].p_offset + i_phdrs[i].p_filesz;
 
/* LOADADDR is the `Base address' from the gELF specification:
`lowest p_vaddr value for a PT_LOAD segment' is P_VADDR from the
first PT_LOAD as PT_LOADs are ordered by P_VADDR. */
if (!loadbase_set && (i_phdrs[i].p_offset & -i_phdrs[i].p_align) == 0)
if (segment_end > high_offset)
{
loadbase = ehdr_vma - (i_phdrs[i].p_vaddr & -i_phdrs[i].p_align);
loadbase_set = TRUE;
high_offset = segment_end;
last_phdr = &i_phdrs[i];
}
 
last_phdr = &i_phdrs[i];
/* If this program header covers offset zero, where the file
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;
 
if (i_phdrs[i].p_align > 1)
{
p_offset &= -i_phdrs[i].p_align;
p_vaddr &= -i_phdrs[i].p_align;
}
if (p_offset == 0)
{
loadbase = ehdr_vma - p_vaddr;
first_phdr = &i_phdrs[i];
}
if (last_phdr == NULL)
}
}
}
if (high_offset == 0)
{
/* There were no PT_LOAD segments, so we don't have anything to read. */
free (x_phdrs);
1728,27 → 1741,42
return NULL;
}
 
/* Trim the last segment so we don't bother with zeros in the last page
that are off the end of the file. However, if the extra bit in that
page includes the section headers, keep them. */
if ((bfd_vma) contents_size > last_phdr->p_offset + last_phdr->p_filesz
&& (bfd_vma) contents_size >= (i_ehdr.e_shoff
+ i_ehdr.e_shnum * i_ehdr.e_shentsize))
shdr_end = 0;
if (i_ehdr.e_shoff != 0 && i_ehdr.e_shnum != 0 && i_ehdr.e_shentsize != 0)
{
contents_size = last_phdr->p_offset + last_phdr->p_filesz;
if ((bfd_vma) contents_size < (i_ehdr.e_shoff
+ i_ehdr.e_shnum * i_ehdr.e_shentsize))
contents_size = i_ehdr.e_shoff + i_ehdr.e_shnum * i_ehdr.e_shentsize;
shdr_end = i_ehdr.e_shoff + i_ehdr.e_shnum * i_ehdr.e_shentsize;
 
if (last_phdr->p_filesz != last_phdr->p_memsz)
{
/* If the last PT_LOAD header has a bss area then ld.so will
have cleared anything past p_filesz, zapping the section
headers. */
}
else if (size >= shdr_end)
high_offset = size;
else
contents_size = last_phdr->p_offset + last_phdr->p_filesz;
{
bfd_vma page_size = get_elf_backend_data (templ)->minpagesize;
bfd_vma segment_end = last_phdr->p_offset + last_phdr->p_filesz;
 
/* Assume we loaded full pages, allowing us to sometimes see
section headers. */
if (page_size > 1 && shdr_end > segment_end)
{
bfd_vma page_end = (segment_end + page_size - 1) & -page_size;
 
if (page_end >= shdr_end)
/* Whee, section headers covered. */
high_offset = shdr_end;
}
}
}
 
/* Now we know the size of the whole image we want read in. */
contents = (bfd_byte *) bfd_zmalloc (contents_size);
contents = (bfd_byte *) bfd_zmalloc (high_offset);
if (contents == NULL)
{
free (x_phdrs);
bfd_set_error (bfd_error_no_memory);
return NULL;
}
 
1755,13 → 1783,22
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 & -i_phdrs[i].p_align;
bfd_vma end = (i_phdrs[i].p_offset + i_phdrs[i].p_filesz
+ i_phdrs[i].p_align - 1) & -i_phdrs[i].p_align;
if (end > (bfd_vma) contents_size)
end = contents_size;
err = target_read_memory ((loadbase + i_phdrs[i].p_vaddr)
& -i_phdrs[i].p_align,
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;
 
/* Extend the beginning of the first pt_load to cover file
header and program headers, if we proved earlier that its
aligned offset is 0. */
if (first_phdr == &i_phdrs[i])
{
vaddr -= start;
start = 0;
}
/* 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,
contents + start, end - start);
if (err)
{
1776,8 → 1813,7
 
/* If the segments visible in memory didn't include the section headers,
then clear them from the file header. */
if ((bfd_vma) contents_size < (i_ehdr.e_shoff
+ i_ehdr.e_shnum * i_ehdr.e_shentsize))
if (high_offset < shdr_end)
{
memset (&x_ehdr.e_shoff, 0, sizeof x_ehdr.e_shoff);
memset (&x_ehdr.e_shnum, 0, sizeof x_ehdr.e_shnum);
1793,7 → 1829,6
if (bim == NULL)
{
free (contents);
bfd_set_error (bfd_error_no_memory);
return NULL;
}
nbfd = _bfd_new_bfd ();
1801,12 → 1836,11
{
free (bim);
free (contents);
bfd_set_error (bfd_error_no_memory);
return NULL;
}
nbfd->filename = "<in-memory>";
nbfd->filename = xstrdup ("<in-memory>");
nbfd->xvec = templ->xvec;
bim->size = contents_size;
bim->size = high_offset;
bim->buffer = contents;
nbfd->iostream = bim;
nbfd->flags = BFD_IN_MEMORY;