summaryrefslogtreecommitdiff
path: root/bfd/mach-o.c
diff options
context:
space:
mode:
authoriains <iains>2012-02-10 11:24:44 +0000
committeriains <iains>2012-02-10 11:24:44 +0000
commit90d8b96b9d446f52ba3e0b4abb97f24b28c122c6 (patch)
tree6256f938987f440fc19642390478efd9a467da81 /bfd/mach-o.c
parenteb616f8f3517e47259cbc213b664750795ad6a05 (diff)
downloadbinutils-redhat-90d8b96b9d446f52ba3e0b4abb97f24b28c122c6.tar.gz
bfd:
* mach-o.c (bfd_mach_o_build_seg_command): Count zerofill section vma additions in their logical, rather than physical order.
Diffstat (limited to 'bfd/mach-o.c')
-rw-r--r--bfd/mach-o.c63
1 files changed, 52 insertions, 11 deletions
diff --git a/bfd/mach-o.c b/bfd/mach-o.c
index 73d4594bc7..a7b9f80467 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)