summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
diff options
context:
space:
mode:
authorPete Cooper <peter_cooper@apple.com>2016-02-06 00:14:15 +0000
committerPete Cooper <peter_cooper@apple.com>2016-02-06 00:14:15 +0000
commit353652f80841b56562b148e7391d6fde251f1db2 (patch)
tree1cef564176e91ed1d82f73b73a58f7d1e67f864d /lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
parentd0078b2dba5e65c65cf934d0784fd42e97eefb34 (diff)
downloadbcm5719-llvm-353652f80841b56562b148e7391d6fde251f1db2.tar.gz
bcm5719-llvm-353652f80841b56562b148e7391d6fde251f1db2.zip
Move creation of "__LINKEDIT" segment. NFC.
We currently tag on a "__LINKEDIT" when we are emitting the segments. However, an upcoming patch aims to set the initprot and maxprot segment members to their correct values, and in order to share code, its better to create this segment for real and handle it in buildFileOffsets the same way ld64 does. The commit for segment protections will add a test for this all being correct so no test here until that code is committed. llvm-svn: 259960
Diffstat (limited to 'lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp')
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp52
1 files changed, 28 insertions, 24 deletions
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
index 6814a16189c..8a11a5c7bac 100644
--- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
@@ -430,9 +430,6 @@ uint32_t MachOFileLayout::loadCommandsSize(uint32_t &count) {
count += _file.segments.size();
// Add section record for each section.
size += _file.sections.size() * sectionSize;
- // Add one LC_SEGMENT for implicit __LINKEDIT segment
- size += segCommandSize;
- ++count;
// If creating a dylib, add LC_ID_DYLIB.
if (_file.fileType == llvm::MachO::MH_DYLIB) {
@@ -595,8 +592,11 @@ void MachOFileLayout::buildFileOffsets() {
<< ", fileOffset=" << fileOffset << "\n");
}
- _segInfo[&sg].fileSize = llvm::alignTo(segFileSize, _file.pageSize);
- fileOffset = llvm::alignTo(fileOffset + segFileSize, _file.pageSize);
+ // round up all segments to page aligned, except __LINKEDIT
+ if (!sg.name.equals("__LINKEDIT")) {
+ _segInfo[&sg].fileSize = llvm::alignTo(segFileSize, _file.pageSize);
+ fileOffset = llvm::alignTo(fileOffset + segFileSize, _file.pageSize);
+ }
_addressOfLinkEdit = sg.address + sg.size;
}
_startOfLinkEdit = fileOffset;
@@ -697,8 +697,30 @@ template <typename T>
std::error_code MachOFileLayout::writeSegmentLoadCommands(uint8_t *&lc) {
uint32_t indirectSymRunningIndex = 0;
for (const Segment &seg : _file.segments) {
- // Write segment command with trailing sections.
+ // Link edit has no sections and a custom range of address, so handle it
+ // specially.
SegExtraInfo &segInfo = _segInfo[&seg];
+ if (seg.name.equals("__LINKEDIT")) {
+ size_t linkeditSize = _endOfLinkEdit - _startOfLinkEdit;
+ typename T::command* cmd = reinterpret_cast<typename T::command*>(lc);
+ cmd->cmd = T::LC;
+ cmd->cmdsize = sizeof(typename T::command);
+ uint8_t *next = lc + cmd->cmdsize;
+ setString16("__LINKEDIT", cmd->segname);
+ cmd->vmaddr = _addressOfLinkEdit;
+ cmd->vmsize = llvm::alignTo(linkeditSize, _file.pageSize);
+ cmd->fileoff = _startOfLinkEdit;
+ cmd->filesize = linkeditSize;
+ cmd->initprot = seg.access;
+ cmd->maxprot = seg.access;
+ cmd->nsects = 0;
+ cmd->flags = 0;
+ if (_swap)
+ swapStruct(*cmd);
+ lc = next;
+ continue;
+ }
+ // Write segment command with trailing sections.
typename T::command* cmd = reinterpret_cast<typename T::command*>(lc);
cmd->cmd = T::LC;
cmd->cmdsize = sizeof(typename T::command)
@@ -738,24 +760,6 @@ std::error_code MachOFileLayout::writeSegmentLoadCommands(uint8_t *&lc) {
}
lc = reinterpret_cast<uint8_t*>(next);
}
- // Add implicit __LINKEDIT segment
- size_t linkeditSize = _endOfLinkEdit - _startOfLinkEdit;
- typename T::command* cmd = reinterpret_cast<typename T::command*>(lc);
- cmd->cmd = T::LC;
- cmd->cmdsize = sizeof(typename T::command);
- uint8_t *next = lc + cmd->cmdsize;
- setString16("__LINKEDIT", cmd->segname);
- cmd->vmaddr = _addressOfLinkEdit;
- cmd->vmsize = llvm::alignTo(linkeditSize, _file.pageSize);
- cmd->fileoff = _startOfLinkEdit;
- cmd->filesize = linkeditSize;
- cmd->maxprot = VM_PROT_READ;
- cmd->initprot = VM_PROT_READ;
- cmd->nsects = 0;
- cmd->flags = 0;
- if (_swap)
- swapStruct(*cmd);
- lc = next;
return std::error_code();
}
OpenPOWER on IntegriCloud