Skip to content

Commit cb50aaf

Browse files
drodriguezllvmbot
authored andcommitted
[llvm-objcopy] Apply encryptable offset to first segment, not section (#130517)
Bug introduced #120995. The LLD code calculates the "size" of the Mach-O headers, and then uses that size to place the segments, but the `__TEXT` section stays at `fileoff` zero. When I wrote the code into llvm-objcopy I calculated the extra space into the initial offset, which moved all the sections back 1 page. Besides the modified test checking for the right `fileoff` values of the sections and the segments, I also manually checked the generated binaries after `llvm-objcopy` using `dyld_info`, as the bug report suggested. Fixes #130472 (cherry picked from commit 8413f4d)
1 parent 63e63f3 commit cb50aaf

File tree

2 files changed

+17
-8
lines changed

2 files changed

+17
-8
lines changed

llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp

+8-5
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,10 @@ uint64_t MachOLayoutBuilder::layoutSegments() {
116116
const bool IsObjectFile =
117117
O.Header.FileType == MachO::HeaderFileType::MH_OBJECT;
118118
uint64_t Offset = IsObjectFile ? (HeaderSize + O.Header.SizeOfCmds) : 0;
119-
if (O.EncryptionInfoCommandIndex) {
120-
// If we are emitting an encryptable binary, our load commands must have a
121-
// separate (non-encrypted) page to themselves.
122-
Offset = alignToPowerOf2(HeaderSize + O.Header.SizeOfCmds, PageSize);
123-
}
119+
// If we are emitting an encryptable binary, our load commands must have a
120+
// separate (non-encrypted) page to themselves.
121+
bool RequiresFirstSectionOutsideFirstPage =
122+
O.EncryptionInfoCommandIndex.has_value();
124123
for (LoadCommand &LC : O.LoadCommands) {
125124
auto &MLC = LC.MachOLoadCommand;
126125
StringRef Segname;
@@ -174,6 +173,10 @@ uint64_t MachOLayoutBuilder::layoutSegments() {
174173
if (!Sec->hasValidOffset()) {
175174
Sec->Offset = 0;
176175
} else {
176+
if (RequiresFirstSectionOutsideFirstPage) {
177+
SectOffset = alignToPowerOf2(SectOffset, PageSize);
178+
RequiresFirstSectionOutsideFirstPage = false;
179+
}
177180
Sec->Offset = SegOffset + SectOffset;
178181
Sec->Size = Sec->Content.size();
179182
SegFileSize = std::max(SegFileSize, SectOffset + Sec->Size);

llvm/test/tools/llvm-objcopy/MachO/strip-with-encryption-info.test

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
# RUN: rm -rf %t && mkdir %t
22
# RUN: yaml2obj %s -o %t/original
33
# RUN: llvm-strip --strip-all %t/original -o %t/stripped
4-
# RUN: llvm-readobj --macho-segment %t/stripped | FileCheck %s
4+
# RUN: llvm-readobj --macho-segment --section-headers %t/stripped | FileCheck %s
5+
6+
# CHECK-LABEL: Sections [
7+
# CHECK: Index: 0
8+
# CHECK-NEXT: Name: __text
9+
# CHECK-NEXT: Segment: __TEXT
10+
# CHECK: Offset: 16384
511

612
# CHECK-LABEL: Name: __PAGEZERO
7-
# CHECK: fileoff: 16384
13+
# CHECK: fileoff: 0
814

915
# CHECK-LABEL: Name: __TEXT
10-
# CHECK: fileoff: 16384
16+
# CHECK: fileoff: 0
1117

1218
# The YAML below is the following code
1319
# int main(int argc, char **argv) { return 0; }

0 commit comments

Comments
 (0)