Rev 5197 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5197 | Rev 6324 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | /* ELF executable support for BFD. |
1 | /* ELF executable support for BFD. |
2 | Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, |
- | |
3 | 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 |
- | |
4 | Free Software Foundation, Inc. |
2 | Copyright (C) 1991-2015 Free Software Foundation, Inc. |
Line 5... | Line 3... | ||
5 | 3 | ||
6 | Written by Fred Fish @ Cygnus Support, from information published |
4 | Written by Fred Fish @ Cygnus Support, from information published |
7 | in "UNIX System V Release 4, Programmers Guide: ANSI C and |
5 | in "UNIX System V Release 4, Programmers Guide: ANSI C and |
Line 71... | Line 69... | ||
71 | #include "bfd.h" |
69 | #include "bfd.h" |
72 | #include "libiberty.h" |
70 | #include "libiberty.h" |
73 | #include "bfdlink.h" |
71 | #include "bfdlink.h" |
74 | #include "libbfd.h" |
72 | #include "libbfd.h" |
75 | #include "elf-bfd.h" |
73 | #include "elf-bfd.h" |
- | 74 | #include "libiberty.h" |
|
Line 76... | Line 75... | ||
76 | 75 | ||
77 | /* Renaming structures, typedefs, macros and functions to be size-specific. */ |
76 | /* Renaming structures, typedefs, macros and functions to be size-specific. */ |
78 | #define Elf_External_Ehdr NAME(Elf,External_Ehdr) |
77 | #define Elf_External_Ehdr NAME(Elf,External_Ehdr) |
79 | #define Elf_External_Sym NAME(Elf,External_Sym) |
78 | #define Elf_External_Sym NAME(Elf,External_Sym) |
Line 604... | Line 603... | ||
604 | && ebd->elf_osabi != ELFOSABI_NONE) |
603 | && ebd->elf_osabi != ELFOSABI_NONE) |
605 | goto got_wrong_format_error; |
604 | goto got_wrong_format_error; |
Line 606... | Line 605... | ||
606 | 605 | ||
607 | if (i_ehdrp->e_shoff != 0) |
606 | if (i_ehdrp->e_shoff != 0) |
608 | { |
607 | { |
609 | bfd_signed_vma where = i_ehdrp->e_shoff; |
- | |
610 | - | ||
611 | if (where != (file_ptr) where) |
- | |
Line 612... | Line 608... | ||
612 | goto got_wrong_format_error; |
608 | file_ptr where = (file_ptr) i_ehdrp->e_shoff; |
613 | 609 | ||
614 | /* Seek to the section header table in the file. */ |
610 | /* Seek to the section header table in the file. */ |
Line 615... | Line 611... | ||
615 | if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0) |
611 | if (bfd_seek (abfd, where, SEEK_SET) != 0) |
616 | goto got_no_match; |
612 | goto got_no_match; |
617 | 613 | ||
Line 656... | Line 652... | ||
656 | if (i_ehdrp->e_shnum > (unsigned int) -1 / sizeof (x_shdr) |
652 | if (i_ehdrp->e_shnum > (unsigned int) -1 / sizeof (x_shdr) |
657 | || i_ehdrp->e_shnum > (unsigned int) -1 / sizeof (i_shdr)) |
653 | || i_ehdrp->e_shnum > (unsigned int) -1 / sizeof (i_shdr)) |
658 | goto got_wrong_format_error; |
654 | goto got_wrong_format_error; |
Line 659... | Line 655... | ||
659 | 655 | ||
660 | where += (i_ehdrp->e_shnum - 1) * sizeof (x_shdr); |
- | |
661 | if (where != (file_ptr) where) |
- | |
662 | goto got_wrong_format_error; |
656 | where += (i_ehdrp->e_shnum - 1) * sizeof (x_shdr); |
663 | if ((bfd_size_type) where <= i_ehdrp->e_shoff) |
657 | if ((bfd_size_type) where <= i_ehdrp->e_shoff) |
Line 664... | Line 658... | ||
664 | goto got_wrong_format_error; |
658 | goto got_wrong_format_error; |
665 | 659 | ||
666 | if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0) |
660 | if (bfd_seek (abfd, where, SEEK_SET) != 0) |
667 | goto got_no_match; |
661 | goto got_no_match; |
Line 668... | Line 662... | ||
668 | if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr)) |
662 | if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr)) |
669 | goto got_no_match; |
663 | goto got_no_match; |
670 | 664 | ||
671 | /* Back to where we were. */ |
665 | /* Back to where we were. */ |
672 | where = i_ehdrp->e_shoff + sizeof (x_shdr); |
666 | where = i_ehdrp->e_shoff + sizeof (x_shdr); |
673 | if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0) |
667 | if (bfd_seek (abfd, where, SEEK_SET) != 0) |
Line 674... | Line 668... | ||
674 | goto got_no_match; |
668 | goto got_no_match; |
Line 680... | Line 674... | ||
680 | if (i_ehdrp->e_shnum != 0) |
674 | if (i_ehdrp->e_shnum != 0) |
681 | { |
675 | { |
682 | Elf_Internal_Shdr *shdrp; |
676 | Elf_Internal_Shdr *shdrp; |
683 | unsigned int num_sec; |
677 | unsigned int num_sec; |
Line -... | Line 678... | ||
- | 678 | ||
- | 679 | #ifndef BFD64 |
|
- | 680 | if (i_ehdrp->e_shnum > ((bfd_size_type) -1) / sizeof (*i_shdrp)) |
|
- | 681 | goto got_wrong_format_error; |
|
684 | 682 | #endif |
|
685 | amt = sizeof (*i_shdrp) * i_ehdrp->e_shnum; |
683 | amt = sizeof (*i_shdrp) * i_ehdrp->e_shnum; |
686 | i_shdrp = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt); |
684 | i_shdrp = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt); |
687 | if (!i_shdrp) |
685 | if (!i_shdrp) |
688 | goto got_no_match; |
686 | goto got_no_match; |
Line 711... | Line 709... | ||
711 | /* PR 10478: Accept Solaris binaries with a sh_link |
709 | /* PR 10478: Accept Solaris binaries with a sh_link |
712 | field set to SHN_BEFORE or SHN_AFTER. */ |
710 | field set to SHN_BEFORE or SHN_AFTER. */ |
713 | switch (ebd->elf_machine_code) |
711 | switch (ebd->elf_machine_code) |
714 | { |
712 | { |
715 | case EM_386: |
713 | case EM_386: |
716 | case EM_486: |
714 | case EM_IAMCU: |
717 | case EM_X86_64: |
715 | case EM_X86_64: |
718 | case EM_OLD_SPARCV9: |
716 | case EM_OLD_SPARCV9: |
719 | case EM_SPARC32PLUS: |
717 | case EM_SPARC32PLUS: |
720 | case EM_SPARCV9: |
718 | case EM_SPARCV9: |
721 | case EM_SPARC: |
719 | case EM_SPARC: |
Line 770... | Line 768... | ||
770 | else |
768 | else |
771 | { |
769 | { |
772 | Elf_Internal_Phdr *i_phdr; |
770 | Elf_Internal_Phdr *i_phdr; |
773 | unsigned int i; |
771 | unsigned int i; |
Line -... | Line 772... | ||
- | 772 | ||
- | 773 | #ifndef BFD64 |
|
- | 774 | if (i_ehdrp->e_phnum > ((bfd_size_type) -1) / sizeof (*i_phdr)) |
|
- | 775 | goto got_wrong_format_error; |
|
774 | 776 | #endif |
|
775 | amt = i_ehdrp->e_phnum * sizeof (Elf_Internal_Phdr); |
777 | amt = i_ehdrp->e_phnum * sizeof (*i_phdr); |
776 | elf_tdata (abfd)->phdr = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt); |
778 | elf_tdata (abfd)->phdr = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt); |
777 | if (elf_tdata (abfd)->phdr == NULL) |
779 | if (elf_tdata (abfd)->phdr == NULL) |
778 | goto got_no_match; |
780 | goto got_no_match; |
779 | if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_phoff, SEEK_SET) != 0) |
781 | if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_phoff, SEEK_SET) != 0) |
Line 1213... | Line 1215... | ||
1213 | ++xver; |
1215 | ++xver; |
1214 | isymend = isymbuf + symcount; |
1216 | isymend = isymbuf + symcount; |
1215 | for (isym = isymbuf + 1, sym = symbase; isym < isymend; isym++, sym++) |
1217 | for (isym = isymbuf + 1, sym = symbase; isym < isymend; isym++, sym++) |
1216 | { |
1218 | { |
1217 | memcpy (&sym->internal_elf_sym, isym, sizeof (Elf_Internal_Sym)); |
1219 | memcpy (&sym->internal_elf_sym, isym, sizeof (Elf_Internal_Sym)); |
1218 | sym->symbol.the_bfd = abfd; |
- | |
Line -... | Line 1220... | ||
- | 1220 | ||
1219 | 1221 | sym->symbol.the_bfd = abfd; |
|
1220 | sym->symbol.name = bfd_elf_sym_name (abfd, hdr, isym, NULL); |
- | |
1221 | 1222 | sym->symbol.name = bfd_elf_sym_name (abfd, hdr, isym, NULL); |
|
Line 1222... | Line 1223... | ||
1222 | sym->symbol.value = isym->st_value; |
1223 | sym->symbol.value = isym->st_value; |
1223 | 1224 | ||
1224 | if (isym->st_shndx == SHN_UNDEF) |
1225 | if (isym->st_shndx == SHN_UNDEF) |
Line 1500... | Line 1501... | ||
1500 | rel_hdr = d->rel.hdr; |
1501 | rel_hdr = d->rel.hdr; |
1501 | reloc_count = rel_hdr ? NUM_SHDR_ENTRIES (rel_hdr) : 0; |
1502 | reloc_count = rel_hdr ? NUM_SHDR_ENTRIES (rel_hdr) : 0; |
1502 | rel_hdr2 = d->rela.hdr; |
1503 | rel_hdr2 = d->rela.hdr; |
1503 | reloc_count2 = rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0; |
1504 | reloc_count2 = rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0; |
Line -... | Line 1505... | ||
- | 1505 | ||
1504 | 1506 | /* PR 17512: file: 0b4f81b7. */ |
|
- | 1507 | if (asect->reloc_count != reloc_count + reloc_count2) |
|
1505 | BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2); |
1508 | return FALSE; |
1506 | BFD_ASSERT ((rel_hdr && asect->rel_filepos == rel_hdr->sh_offset) |
1509 | BFD_ASSERT ((rel_hdr && asect->rel_filepos == rel_hdr->sh_offset) |
Line 1507... | Line 1510... | ||
1507 | || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset)); |
1510 | || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset)); |
1508 | 1511 | ||
Line 1586... | Line 1589... | ||
1586 | fprintf (stderr, "e_shentsize = %ld\n", (long) ehdrp->e_shentsize); |
1589 | fprintf (stderr, "e_shentsize = %ld\n", (long) ehdrp->e_shentsize); |
1587 | } |
1590 | } |
1588 | #endif |
1591 | #endif |
1589 | 1592 | ||
1590 | /* Create a new BFD as if by bfd_openr. Rather than opening a file, |
1593 | /* Create a new BFD as if by bfd_openr. Rather than opening a file, |
1591 | reconstruct an ELF file by reading the segments out of remote memory |
1594 | reconstruct an ELF file by reading the segments out of remote |
1592 | based on the ELF file header at EHDR_VMA and the ELF program headers it |
1595 | memory based on the ELF file header at EHDR_VMA and the ELF program |
- | 1596 | headers it points to. If non-zero, SIZE is the known extent of the |
|
1593 | points to. If not null, *LOADBASEP is filled in with the difference |
1597 | object. If not null, *LOADBASEP is filled in with the difference |
1594 | between the VMAs from which the segments were read, and the VMAs the |
1598 | between the VMAs from which the segments were read, and the VMAs |
1595 | file headers (and hence BFD's idea of each section's VMA) put them at. |
1599 | the file headers (and hence BFD's idea of each section's VMA) put |
- | 1600 | them at. |
|
1596 | 1601 | ||
1597 | The function TARGET_READ_MEMORY is called to copy LEN bytes from the |
1602 | The function TARGET_READ_MEMORY is called to copy LEN bytes from |
1598 | remote memory at target address VMA into the local buffer at MYADDR; it |
1603 | the remote memory at target address VMA into the local buffer at |
1599 | should return zero on success or an `errno' code on failure. TEMPL must |
1604 | MYADDR; it should return zero on success or an `errno' code on |
1600 | be a BFD for a target with the word size and byte order found in the |
1605 | failure. TEMPL must be a BFD for a target with the word size and |
1601 | remote memory. */ |
1606 | byte order found in the remote memory. */ |
Line 1602... | Line 1607... | ||
1602 | 1607 | ||
1603 | bfd * |
1608 | bfd * |
1604 | NAME(_bfd_elf,bfd_from_remote_memory) |
1609 | NAME(_bfd_elf,bfd_from_remote_memory) |
1605 | (bfd *templ, |
1610 | (bfd *templ, |
- | 1611 | bfd_vma ehdr_vma, |
|
1606 | bfd_vma ehdr_vma, |
1612 | bfd_size_type size, |
1607 | bfd_vma *loadbasep, |
1613 | bfd_vma *loadbasep, |
1608 | int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type)) |
1614 | int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type)) |
1609 | { |
1615 | { |
1610 | Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ |
1616 | Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ |
1611 | Elf_Internal_Ehdr i_ehdr; /* Elf file header, internal form */ |
1617 | Elf_Internal_Ehdr i_ehdr; /* Elf file header, internal form */ |
1612 | Elf_External_Phdr *x_phdrs; |
1618 | Elf_External_Phdr *x_phdrs; |
1613 | Elf_Internal_Phdr *i_phdrs, *last_phdr; |
1619 | Elf_Internal_Phdr *i_phdrs, *last_phdr, *first_phdr; |
1614 | bfd *nbfd; |
1620 | bfd *nbfd; |
1615 | struct bfd_in_memory *bim; |
- | |
1616 | int contents_size; |
1621 | struct bfd_in_memory *bim; |
1617 | bfd_byte *contents; |
1622 | bfd_byte *contents; |
1618 | int err; |
1623 | int err; |
- | 1624 | unsigned int i; |
|
- | 1625 | bfd_vma high_offset; |
|
1619 | unsigned int i; |
1626 | bfd_vma shdr_end; |
1620 | bfd_vma loadbase; |
- | |
Line 1621... | Line 1627... | ||
1621 | bfd_boolean loadbase_set; |
1627 | bfd_vma loadbase; |
1622 | 1628 | ||
1623 | /* Read in the ELF header in external format. */ |
1629 | /* Read in the ELF header in external format. */ |
1624 | err = target_read_memory (ehdr_vma, (bfd_byte *) &x_ehdr, sizeof x_ehdr); |
1630 | err = target_read_memory (ehdr_vma, (bfd_byte *) &x_ehdr, sizeof x_ehdr); |
Line 1676... | Line 1682... | ||
1676 | } |
1682 | } |
Line 1677... | Line 1683... | ||
1677 | 1683 | ||
1678 | x_phdrs = (Elf_External_Phdr *) |
1684 | x_phdrs = (Elf_External_Phdr *) |
1679 | bfd_malloc (i_ehdr.e_phnum * (sizeof *x_phdrs + sizeof *i_phdrs)); |
1685 | bfd_malloc (i_ehdr.e_phnum * (sizeof *x_phdrs + sizeof *i_phdrs)); |
1680 | if (x_phdrs == NULL) |
- | |
1681 | { |
- | |
1682 | bfd_set_error (bfd_error_no_memory); |
1686 | if (x_phdrs == NULL) |
1683 | return NULL; |
- | |
1684 | } |
1687 | return NULL; |
1685 | err = target_read_memory (ehdr_vma + i_ehdr.e_phoff, (bfd_byte *) x_phdrs, |
1688 | err = target_read_memory (ehdr_vma + i_ehdr.e_phoff, (bfd_byte *) x_phdrs, |
1686 | i_ehdr.e_phnum * sizeof x_phdrs[0]); |
1689 | i_ehdr.e_phnum * sizeof x_phdrs[0]); |
1687 | if (err) |
1690 | if (err) |
1688 | { |
1691 | { |
Line 1691... | Line 1694... | ||
1691 | errno = err; |
1694 | errno = err; |
1692 | return NULL; |
1695 | return NULL; |
1693 | } |
1696 | } |
1694 | i_phdrs = (Elf_Internal_Phdr *) &x_phdrs[i_ehdr.e_phnum]; |
1697 | i_phdrs = (Elf_Internal_Phdr *) &x_phdrs[i_ehdr.e_phnum]; |
Line -... | Line 1698... | ||
- | 1698 | ||
1695 | 1699 | high_offset = 0; |
|
- | 1700 | loadbase = 0; |
|
1696 | contents_size = 0; |
1701 | first_phdr = NULL; |
1697 | last_phdr = NULL; |
- | |
1698 | loadbase = ehdr_vma; |
- | |
1699 | loadbase_set = FALSE; |
1702 | last_phdr = NULL; |
1700 | for (i = 0; i < i_ehdr.e_phnum; ++i) |
1703 | for (i = 0; i < i_ehdr.e_phnum; ++i) |
1701 | { |
1704 | { |
1702 | elf_swap_phdr_in (templ, &x_phdrs[i], &i_phdrs[i]); |
1705 | elf_swap_phdr_in (templ, &x_phdrs[i], &i_phdrs[i]); |
1703 | if (i_phdrs[i].p_type == PT_LOAD) |
1706 | if (i_phdrs[i].p_type == PT_LOAD) |
1704 | { |
- | |
1705 | bfd_vma segment_end; |
1707 | { |
1706 | segment_end = (i_phdrs[i].p_offset + i_phdrs[i].p_filesz |
- | |
1707 | + i_phdrs[i].p_align - 1) & -i_phdrs[i].p_align; |
- | |
1708 | if (segment_end > (bfd_vma) contents_size) |
- | |
1709 | contents_size = segment_end; |
1708 | bfd_vma segment_end = i_phdrs[i].p_offset + i_phdrs[i].p_filesz; |
1710 | - | ||
1711 | /* LOADADDR is the `Base address' from the gELF specification: |
- | |
1712 | `lowest p_vaddr value for a PT_LOAD segment' is P_VADDR from the |
- | |
1713 | first PT_LOAD as PT_LOADs are ordered by P_VADDR. */ |
1709 | |
1714 | if (!loadbase_set && (i_phdrs[i].p_offset & -i_phdrs[i].p_align) == 0) |
1710 | if (segment_end > high_offset) |
1715 | { |
1711 | { |
1716 | loadbase = ehdr_vma - (i_phdrs[i].p_vaddr & -i_phdrs[i].p_align); |
1712 | high_offset = segment_end; |
1717 | loadbase_set = TRUE; |
1713 | last_phdr = &i_phdrs[i]; |
Line -... | Line 1714... | ||
- | 1714 | } |
|
- | 1715 | ||
- | 1716 | /* If this program header covers offset zero, where the file |
|
- | 1717 | header sits, then we can figure out the loadbase. */ |
|
- | 1718 | if (first_phdr == NULL) |
|
- | 1719 | { |
|
- | 1720 | bfd_vma p_offset = i_phdrs[i].p_offset; |
|
- | 1721 | bfd_vma p_vaddr = i_phdrs[i].p_vaddr; |
|
- | 1722 | ||
- | 1723 | if (i_phdrs[i].p_align > 1) |
|
- | 1724 | { |
|
- | 1725 | p_offset &= -i_phdrs[i].p_align; |
|
- | 1726 | p_vaddr &= -i_phdrs[i].p_align; |
|
- | 1727 | } |
|
- | 1728 | if (p_offset == 0) |
|
1718 | } |
1729 | { |
- | 1730 | loadbase = ehdr_vma - p_vaddr; |
|
- | 1731 | first_phdr = &i_phdrs[i]; |
|
1719 | 1732 | } |
|
1720 | last_phdr = &i_phdrs[i]; |
1733 | } |
1721 | } |
1734 | } |
1722 | } |
1735 | } |
1723 | if (last_phdr == NULL) |
1736 | if (high_offset == 0) |
1724 | { |
1737 | { |
1725 | /* There were no PT_LOAD segments, so we don't have anything to read. */ |
1738 | /* There were no PT_LOAD segments, so we don't have anything to read. */ |
1726 | free (x_phdrs); |
1739 | free (x_phdrs); |
1727 | bfd_set_error (bfd_error_wrong_format); |
1740 | bfd_set_error (bfd_error_wrong_format); |
Line 1728... | Line -... | ||
1728 | return NULL; |
- | |
1729 | } |
- | |
1730 | - | ||
1731 | /* Trim the last segment so we don't bother with zeros in the last page |
- | |
1732 | that are off the end of the file. However, if the extra bit in that |
1741 | return NULL; |
1733 | page includes the section headers, keep them. */ |
1742 | } |
1734 | if ((bfd_vma) contents_size > last_phdr->p_offset + last_phdr->p_filesz |
1743 | |
1735 | && (bfd_vma) contents_size >= (i_ehdr.e_shoff |
1744 | shdr_end = 0; |
- | 1745 | if (i_ehdr.e_shoff != 0 && i_ehdr.e_shnum != 0 && i_ehdr.e_shentsize != 0) |
|
1736 | + i_ehdr.e_shnum * i_ehdr.e_shentsize)) |
1746 | { |
- | 1747 | shdr_end = i_ehdr.e_shoff + i_ehdr.e_shnum * i_ehdr.e_shentsize; |
|
1737 | { |
1748 | |
1738 | contents_size = last_phdr->p_offset + last_phdr->p_filesz; |
1749 | if (last_phdr->p_filesz != last_phdr->p_memsz) |
- | 1750 | { |
|
1739 | if ((bfd_vma) contents_size < (i_ehdr.e_shoff |
1751 | /* If the last PT_LOAD header has a bss area then ld.so will |
- | 1752 | have cleared anything past p_filesz, zapping the section |
|
- | 1753 | headers. */ |
|
1740 | + i_ehdr.e_shnum * i_ehdr.e_shentsize)) |
1754 | } |
- | 1755 | else if (size >= shdr_end) |
|
- | 1756 | high_offset = size; |
|
1741 | contents_size = i_ehdr.e_shoff + i_ehdr.e_shnum * i_ehdr.e_shentsize; |
1757 | else |
- | 1758 | { |
|
- | 1759 | bfd_vma page_size = get_elf_backend_data (templ)->minpagesize; |
|
- | 1760 | bfd_vma segment_end = last_phdr->p_offset + last_phdr->p_filesz; |
|
- | 1761 | ||
- | 1762 | /* Assume we loaded full pages, allowing us to sometimes see |
|
- | 1763 | section headers. */ |
|
- | 1764 | if (page_size > 1 && shdr_end > segment_end) |
|
- | 1765 | { |
|
- | 1766 | bfd_vma page_end = (segment_end + page_size - 1) & -page_size; |
|
- | 1767 | ||
- | 1768 | if (page_end >= shdr_end) |
|
- | 1769 | /* Whee, section headers covered. */ |
|
- | 1770 | high_offset = shdr_end; |
|
Line 1742... | Line 1771... | ||
1742 | } |
1771 | } |
1743 | else |
1772 | } |
1744 | contents_size = last_phdr->p_offset + last_phdr->p_filesz; |
1773 | } |
1745 | 1774 | ||
1746 | /* Now we know the size of the whole image we want read in. */ |
1775 | /* Now we know the size of the whole image we want read in. */ |
1747 | contents = (bfd_byte *) bfd_zmalloc (contents_size); |
- | |
1748 | if (contents == NULL) |
1776 | contents = (bfd_byte *) bfd_zmalloc (high_offset); |
1749 | { |
1777 | if (contents == NULL) |
Line 1750... | Line 1778... | ||
1750 | free (x_phdrs); |
1778 | { |
1751 | bfd_set_error (bfd_error_no_memory); |
1779 | free (x_phdrs); |
1752 | return NULL; |
1780 | return NULL; |
1753 | } |
1781 | } |
1754 | 1782 | ||
1755 | for (i = 0; i < i_ehdr.e_phnum; ++i) |
1783 | for (i = 0; i < i_ehdr.e_phnum; ++i) |
- | 1784 | if (i_phdrs[i].p_type == PT_LOAD) |
|
- | 1785 | { |
|
- | 1786 | bfd_vma start = i_phdrs[i].p_offset; |
|
- | 1787 | bfd_vma end = start + i_phdrs[i].p_filesz; |
|
1756 | if (i_phdrs[i].p_type == PT_LOAD) |
1788 | bfd_vma vaddr = i_phdrs[i].p_vaddr; |
- | 1789 | ||
- | 1790 | /* Extend the beginning of the first pt_load to cover file |
|
1757 | { |
1791 | header and program headers, if we proved earlier that its |
- | 1792 | aligned offset is 0. */ |
|
1758 | bfd_vma start = i_phdrs[i].p_offset & -i_phdrs[i].p_align; |
1793 | if (first_phdr == &i_phdrs[i]) |
1759 | bfd_vma end = (i_phdrs[i].p_offset + i_phdrs[i].p_filesz |
1794 | { |
- | 1795 | vaddr -= start; |
|
- | 1796 | start = 0; |
|
1760 | + i_phdrs[i].p_align - 1) & -i_phdrs[i].p_align; |
1797 | } |
1761 | if (end > (bfd_vma) contents_size) |
1798 | /* Extend the end of the last pt_load to cover section headers. */ |
1762 | end = contents_size; |
1799 | if (last_phdr == &i_phdrs[i]) |
1763 | err = target_read_memory ((loadbase + i_phdrs[i].p_vaddr) |
1800 | end = high_offset; |
1764 | & -i_phdrs[i].p_align, |
1801 | err = target_read_memory (loadbase + vaddr, |
Line 1774... | Line 1811... | ||
1774 | } |
1811 | } |
1775 | free (x_phdrs); |
1812 | free (x_phdrs); |
Line 1776... | Line 1813... | ||
1776 | 1813 | ||
1777 | /* If the segments visible in memory didn't include the section headers, |
1814 | /* If the segments visible in memory didn't include the section headers, |
1778 | then clear them from the file header. */ |
1815 | then clear them from the file header. */ |
1779 | if ((bfd_vma) contents_size < (i_ehdr.e_shoff |
- | |
1780 | + i_ehdr.e_shnum * i_ehdr.e_shentsize)) |
1816 | if (high_offset < shdr_end) |
1781 | { |
1817 | { |
1782 | memset (&x_ehdr.e_shoff, 0, sizeof x_ehdr.e_shoff); |
1818 | memset (&x_ehdr.e_shoff, 0, sizeof x_ehdr.e_shoff); |
1783 | memset (&x_ehdr.e_shnum, 0, sizeof x_ehdr.e_shnum); |
1819 | memset (&x_ehdr.e_shnum, 0, sizeof x_ehdr.e_shnum); |
1784 | memset (&x_ehdr.e_shstrndx, 0, sizeof x_ehdr.e_shstrndx); |
1820 | memset (&x_ehdr.e_shstrndx, 0, sizeof x_ehdr.e_shstrndx); |
Line 1791... | Line 1827... | ||
1791 | /* Now we have a memory image of the ELF file contents. Make a BFD. */ |
1827 | /* Now we have a memory image of the ELF file contents. Make a BFD. */ |
1792 | bim = (struct bfd_in_memory *) bfd_malloc (sizeof (struct bfd_in_memory)); |
1828 | bim = (struct bfd_in_memory *) bfd_malloc (sizeof (struct bfd_in_memory)); |
1793 | if (bim == NULL) |
1829 | if (bim == NULL) |
1794 | { |
1830 | { |
1795 | free (contents); |
1831 | free (contents); |
1796 | bfd_set_error (bfd_error_no_memory); |
- | |
1797 | return NULL; |
1832 | return NULL; |
1798 | } |
1833 | } |
1799 | nbfd = _bfd_new_bfd (); |
1834 | nbfd = _bfd_new_bfd (); |
1800 | if (nbfd == NULL) |
1835 | if (nbfd == NULL) |
1801 | { |
1836 | { |
1802 | free (bim); |
1837 | free (bim); |
1803 | free (contents); |
1838 | free (contents); |
1804 | bfd_set_error (bfd_error_no_memory); |
- | |
1805 | return NULL; |
1839 | return NULL; |
1806 | } |
1840 | } |
1807 | nbfd->filename = " |
1841 | nbfd->filename = xstrdup (" |
1808 | nbfd->xvec = templ->xvec; |
1842 | nbfd->xvec = templ->xvec; |
1809 | bim->size = contents_size; |
1843 | bim->size = high_offset; |
1810 | bim->buffer = contents; |
1844 | bim->buffer = contents; |
1811 | nbfd->iostream = bim; |
1845 | nbfd->iostream = bim; |
1812 | nbfd->flags = BFD_IN_MEMORY; |
1846 | nbfd->flags = BFD_IN_MEMORY; |
1813 | nbfd->iovec = &_bfd_memory_iovec; |
1847 | nbfd->iovec = &_bfd_memory_iovec; |
1814 | nbfd->origin = 0; |
1848 | nbfd->origin = 0; |