[lld] r212030 - MachO: calculate segment offsets in final MachO files properly.
Tim Northover
tnorthover at apple.com
Mon Jun 30 02:49:30 PDT 2014
Author: tnorthover
Date: Mon Jun 30 04:49:30 2014
New Revision: 212030
URL: http://llvm.org/viewvc/llvm-project?rev=212030&view=rev
Log:
MachO: calculate segment offsets in final MachO files properly.
Because of how we were calculating fileOffset and fileSize for segments, most
ended up at a single offset in a finalised MachO file. This meant the data
often didn't even get written in the final object, let alone where it would be
useful.
Added:
lld/trunk/test/mach-o/exe-offsets.yaml
Modified:
lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp?rev=212030&r1=212029&r2=212030&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp Mon Jun 30 04:49:30 2014
@@ -142,6 +142,7 @@ private:
struct SegExtraInfo {
uint32_t fileOffset;
+ uint32_t fileSize;
std::vector<const Section*> sections;
};
typedef std::map<const Segment*, SegExtraInfo> SegMap;
@@ -423,23 +424,32 @@ void MachOFileLayout::buildFileOffsets()
DEBUG_WITH_TYPE("MachOFileLayout",
llvm::dbgs() << "buildFileOffsets()\n");
for (const Segment &sg : _file.segments) {
- // FIXME: 4096 should be inferred from segments in normalized file.
- _segInfo[&sg].fileOffset = llvm::RoundUpToAlignment(fileOffset, 4096);
+ _segInfo[&sg].fileOffset = fileOffset;
if ((_seg1addr == INT64_MAX) && sg.access)
_seg1addr = sg.address;
DEBUG_WITH_TYPE("MachOFileLayout",
llvm::dbgs() << " segment=" << sg.name
<< ", fileOffset=" << _segInfo[&sg].fileOffset << "\n");
+
+ uint32_t segFileSize = 0;
for (const Section *s : _segInfo[&sg].sections) {
- fileOffset = s->address - sg.address + _segInfo[&sg].fileOffset;
- _sectInfo[s].fileOffset = fileOffset;
+ uint32_t sectOffset = s->address - sg.address;
+ uint32_t sectFileSize =
+ s->type == llvm::MachO::S_ZEROFILL ? 0 : s->content.size();
+ segFileSize = std::max(segFileSize, sectOffset + sectFileSize);
+
+ _sectInfo[s].fileOffset = _segInfo[&sg].fileOffset + sectOffset;
DEBUG_WITH_TYPE("MachOFileLayout",
llvm::dbgs() << " section=" << s->sectionName
<< ", fileOffset=" << fileOffset << "\n");
}
+
+ // FIXME: 4096 should be inferred from segments in normalized file.
+ _segInfo[&sg].fileSize = llvm::RoundUpToAlignment(segFileSize, 4096);
+ fileOffset = llvm::RoundUpToAlignment(fileOffset + segFileSize, 4096);
_addressOfLinkEdit = sg.address + sg.size;
}
- _startOfLinkEdit = llvm::RoundUpToAlignment(fileOffset, 4096);
+ _startOfLinkEdit = fileOffset;
}
@@ -537,7 +547,7 @@ std::error_code MachOFileLayout::writeSe
cmd->vmaddr = seg.address;
cmd->vmsize = seg.size;
cmd->fileoff = segInfo.fileOffset;
- cmd->filesize = seg.access ? seg.size : Hex64(0);
+ cmd->filesize = segInfo.fileSize;
cmd->maxprot = seg.access;
cmd->initprot = seg.access;
cmd->nsects = segInfo.sections.size();
Added: lld/trunk/test/mach-o/exe-offsets.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/exe-offsets.yaml?rev=212030&view=auto
==============================================================================
--- lld/trunk/test/mach-o/exe-offsets.yaml (added)
+++ lld/trunk/test/mach-o/exe-offsets.yaml Mon Jun 30 04:49:30 2014
@@ -0,0 +1,44 @@
+# RUN: lld -flavor darwin -arch x86_64 %s -o %t -e start
+# RUN: llvm-readobj -sections %t | FileCheck %s
+
+# Make sure data gets put at offset
+
+--- !native
+defined-atoms:
+ - name: start
+ scope: global
+ content: [ 90 ]
+
+ - name: _s1
+ type: data
+ content: [ 31, 32, 33, 34 ]
+
+ - name: _s2
+ type: zero-fill
+ size: 8192
+
+ - name: _s3
+ type: zero-fill
+ size: 100
+
+ - name: _s4
+ type: data
+ content: [ 01 ]
+
+# CHECK-LABEL: Section {
+# CHECK: Name: __text
+# CHECK: Segment: __TEXT
+# CHECK: Size: 0x1
+# CHECK: Offset: 0
+
+# CHECK-LABEL: Section {
+# CHECK: Name: __data
+# CHECK: Segment: __DATA
+# CHECK: Size: 0x5
+# CHECK: Offset: 4096
+
+# CHECK-LABEL: Section {
+# CHECK: Name: ___bss
+# CHECK: Segment: __DATA
+# CHECK: Size: 0x0
+# CHECK: Offset: 4101
More information about the llvm-commits
mailing list