aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2007-08-06 22:53:27 +0000
committerAlan Modra <amodra@gmail.com>2007-08-06 22:53:27 +0000
commitd5191d0cd49227608c80ab220eb31bf795bfd6b1 (patch)
treee0331156065b559ad09151ea5672386b5a160651 /bfd
parent5eda1c47e4b0c1e1fb4cb0273c5cd9488f55d316 (diff)
downloadfsf-binutils-gdb-d5191d0cd49227608c80ab220eb31bf795bfd6b1.zip
fsf-binutils-gdb-d5191d0cd49227608c80ab220eb31bf795bfd6b1.tar.gz
fsf-binutils-gdb-d5191d0cd49227608c80ab220eb31bf795bfd6b1.tar.bz2
* elf.c: (_bfd_elf_make_section_from_phdr): Properly handle
bss segments.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog5
-rw-r--r--bfd/elf.c79
2 files changed, 54 insertions, 30 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index cac533f..ea261aa 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,8 @@
+2007-08-07 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c: (_bfd_elf_make_section_from_phdr): Properly handle
+ bss segments.
+
2007-08-06 Daniel Jacobowitz <dan@codesourcery.com>
* Makefile.am (BUILD_HFILES): Clean bfd_stdint.h.
diff --git a/bfd/elf.c b/bfd/elf.c
index 4bc5a78..ee0339b 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -2223,7 +2223,7 @@ _bfd_elf_new_section_hook (bfd *abfd, asection *sec)
for the single program segment. The first has the length specified by
the file size of the segment, and the second has the length specified
by the difference between the two sizes. In effect, the segment is split
- into it's initialized and uninitialized parts.
+ into its initialized and uninitialized parts.
*/
@@ -2242,40 +2242,46 @@ _bfd_elf_make_section_from_phdr (bfd *abfd,
split = ((hdr->p_memsz > 0)
&& (hdr->p_filesz > 0)
&& (hdr->p_memsz > hdr->p_filesz));
- sprintf (namebuf, "%s%d%s", typename, index, split ? "a" : "");
- len = strlen (namebuf) + 1;
- name = bfd_alloc (abfd, len);
- if (!name)
- return FALSE;
- memcpy (name, namebuf, len);
- newsect = bfd_make_section (abfd, name);
- if (newsect == NULL)
- return FALSE;
- newsect->vma = hdr->p_vaddr;
- newsect->lma = hdr->p_paddr;
- newsect->size = hdr->p_filesz;
- newsect->filepos = hdr->p_offset;
- newsect->flags |= SEC_HAS_CONTENTS;
- newsect->alignment_power = bfd_log2 (hdr->p_align);
- if (hdr->p_type == PT_LOAD)
- {
- newsect->flags |= SEC_ALLOC;
- newsect->flags |= SEC_LOAD;
- if (hdr->p_flags & PF_X)
+
+ if (hdr->p_filesz > 0)
+ {
+ sprintf (namebuf, "%s%d%s", typename, index, split ? "a" : "");
+ len = strlen (namebuf) + 1;
+ name = bfd_alloc (abfd, len);
+ if (!name)
+ return FALSE;
+ memcpy (name, namebuf, len);
+ newsect = bfd_make_section (abfd, name);
+ if (newsect == NULL)
+ return FALSE;
+ newsect->vma = hdr->p_vaddr;
+ newsect->lma = hdr->p_paddr;
+ newsect->size = hdr->p_filesz;
+ newsect->filepos = hdr->p_offset;
+ newsect->flags |= SEC_HAS_CONTENTS;
+ newsect->alignment_power = bfd_log2 (hdr->p_align);
+ if (hdr->p_type == PT_LOAD)
+ {
+ newsect->flags |= SEC_ALLOC;
+ newsect->flags |= SEC_LOAD;
+ if (hdr->p_flags & PF_X)
+ {
+ /* FIXME: all we known is that it has execute PERMISSION,
+ may be data. */
+ newsect->flags |= SEC_CODE;
+ }
+ }
+ if (!(hdr->p_flags & PF_W))
{
- /* FIXME: all we known is that it has execute PERMISSION,
- may be data. */
- newsect->flags |= SEC_CODE;
+ newsect->flags |= SEC_READONLY;
}
}
- if (!(hdr->p_flags & PF_W))
- {
- newsect->flags |= SEC_READONLY;
- }
- if (split)
+ if (hdr->p_memsz > hdr->p_filesz)
{
- sprintf (namebuf, "%s%db", typename, index);
+ bfd_vma align;
+
+ sprintf (namebuf, "%s%d%s", typename, index, split ? "b" : "");
len = strlen (namebuf) + 1;
name = bfd_alloc (abfd, len);
if (!name)
@@ -2287,8 +2293,21 @@ _bfd_elf_make_section_from_phdr (bfd *abfd,
newsect->vma = hdr->p_vaddr + hdr->p_filesz;
newsect->lma = hdr->p_paddr + hdr->p_filesz;
newsect->size = hdr->p_memsz - hdr->p_filesz;
+ newsect->filepos = hdr->p_offset + hdr->p_filesz;
+ align = newsect->vma & -newsect->vma;
+ if (align == 0 || align > hdr->p_align)
+ align = hdr->p_align;
+ newsect->alignment_power = bfd_log2 (align);
if (hdr->p_type == PT_LOAD)
{
+ /* Hack for gdb. Segments that have not been modified do
+ not have their contents written to a core file, on the
+ assumption that a debugger can find the contents in the
+ executable. We flag this case by setting the fake
+ section size to zero. Note that "real" bss sections will
+ always have their contents dumped to the core file. */
+ if (bfd_get_format (abfd) == bfd_core)
+ newsect->size = 0;
newsect->flags |= SEC_ALLOC;
if (hdr->p_flags & PF_X)
newsect->flags |= SEC_CODE;