From 09903f4b533109ab6d161a6c9b513b6f85aa8028 Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Fri, 10 Feb 2012 11:24:44 +0000 Subject: [PATCH] bfd: * mach-o.c (bfd_mach_o_build_seg_command): Count zerofill section vma additions in their logical, rather than physical order. --- bfd/ChangeLog | 5 ++++ bfd/mach-o.c | 63 ++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 57 insertions(+), 11 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 3fbda984899..1f8f30e6215 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2012-02-10 Iain Sandoe + + * mach-o.c (bfd_mach_o_build_seg_command): Count zerofill section + vma additions in their logical, rather than physical order. + 2012-02-10 Iain Sandoe * mach-o.c (mach_o_section_name_xlat): Correct eh-frame section diff --git a/bfd/mach-o.c b/bfd/mach-o.c index 73d4594bc75..a7b9f80467f 100644 --- a/bfd/mach-o.c +++ b/bfd/mach-o.c @@ -2026,7 +2026,12 @@ bfd_mach_o_build_seg_command (const char *segment, seg->sect_head = NULL; seg->sect_tail = NULL; - /* Append sections to the segment. */ + /* Append sections to the segment. + + This is a little tedious, we have to honor the need to account zerofill + sections after all the rest. This forces us to do the calculation of + total vmsize in three passes so that any alignment increments are + properly accounted. */ for (i = 0; i < mdata->nsects; ++i) { @@ -2039,14 +2044,10 @@ bfd_mach_o_build_seg_command (const char *segment, && strncmp (segment, s->segname, BFD_MACH_O_SEGNAME_SIZE) != 0) continue; + /* Although we account for zerofill section sizes in vm order, they are + placed in the file in source sequence. */ bfd_mach_o_append_section_to_segment (seg, sec); - s->offset = 0; - if (s->size > 0) - { - seg->vmsize = FILE_ALIGN (seg->vmsize, s->align); - seg->vmsize += s->size; - } /* Zerofill sections have zero file size & offset, and are not written. */ @@ -2057,19 +2058,59 @@ bfd_mach_o_build_seg_command (const char *segment, if (s->size > 0) { + seg->vmsize = FILE_ALIGN (seg->vmsize, s->align); + seg->vmsize += s->size; + + seg->filesize = FILE_ALIGN (seg->filesize, s->align); + seg->filesize += s->size; + mdata->filelen = FILE_ALIGN (mdata->filelen, s->align); s->offset = mdata->filelen; } sec->filepos = s->offset; - mdata->filelen += s->size; } - seg->filesize = mdata->filelen - seg->fileoff; - seg->filesize = FILE_ALIGN(seg->filesize, 2); + /* Now pass through again, for zerofill, only now we just update the vmsize. */ + for (i = 0; i < mdata->nsects; ++i) + { + bfd_mach_o_section *s = mdata->sections[i]; + + if ((s->flags & BFD_MACH_O_SECTION_TYPE_MASK) != BFD_MACH_O_S_ZEROFILL) + continue; + + if (! is_mho + && strncmp (segment, s->segname, BFD_MACH_O_SEGNAME_SIZE) != 0) + continue; + + if (s->size > 0) + { + seg->vmsize = FILE_ALIGN (seg->vmsize, s->align); + seg->vmsize += s->size; + } + } + + /* Now pass through again, for zerofill_GB. */ + for (i = 0; i < mdata->nsects; ++i) + { + bfd_mach_o_section *s = mdata->sections[i]; + + if ((s->flags & BFD_MACH_O_SECTION_TYPE_MASK) != BFD_MACH_O_S_GB_ZEROFILL) + continue; + + if (! is_mho + && strncmp (segment, s->segname, BFD_MACH_O_SEGNAME_SIZE) != 0) + continue; + + if (s->size > 0) + { + seg->vmsize = FILE_ALIGN (seg->vmsize, s->align); + seg->vmsize += s->size; + } + } - /* Allocate relocation room. */ + /* Allocate space for the relocations. */ mdata->filelen = FILE_ALIGN(mdata->filelen, 2); for (i = 0; i < mdata->nsects; ++i) -- 2.30.2