https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/131398
Backport 8413f4d837a96458104f63bab72c751b8285a458 Requested by: @nikic >From cb50aaf8a11b89f2785641fba5ffd4b67f566a32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodr=C3=ADguez=20Troiti=C3=B1o?= <drodrig...@users.noreply.github.com> Date: Fri, 14 Mar 2025 13:43:48 -0700 Subject: [PATCH] [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 8413f4d837a96458104f63bab72c751b8285a458) --- llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp | 13 ++++++++----- .../MachO/strip-with-encryption-info.test | 12 +++++++++--- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp b/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp index d4eb6a9b9fc0b..8ecd669e67178 100644 --- a/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp +++ b/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp @@ -116,11 +116,10 @@ uint64_t MachOLayoutBuilder::layoutSegments() { const bool IsObjectFile = O.Header.FileType == MachO::HeaderFileType::MH_OBJECT; uint64_t Offset = IsObjectFile ? (HeaderSize + O.Header.SizeOfCmds) : 0; - if (O.EncryptionInfoCommandIndex) { - // If we are emitting an encryptable binary, our load commands must have a - // separate (non-encrypted) page to themselves. - Offset = alignToPowerOf2(HeaderSize + O.Header.SizeOfCmds, PageSize); - } + // If we are emitting an encryptable binary, our load commands must have a + // separate (non-encrypted) page to themselves. + bool RequiresFirstSectionOutsideFirstPage = + O.EncryptionInfoCommandIndex.has_value(); for (LoadCommand &LC : O.LoadCommands) { auto &MLC = LC.MachOLoadCommand; StringRef Segname; @@ -174,6 +173,10 @@ uint64_t MachOLayoutBuilder::layoutSegments() { if (!Sec->hasValidOffset()) { Sec->Offset = 0; } else { + if (RequiresFirstSectionOutsideFirstPage) { + SectOffset = alignToPowerOf2(SectOffset, PageSize); + RequiresFirstSectionOutsideFirstPage = false; + } Sec->Offset = SegOffset + SectOffset; Sec->Size = Sec->Content.size(); SegFileSize = std::max(SegFileSize, SectOffset + Sec->Size); diff --git a/llvm/test/tools/llvm-objcopy/MachO/strip-with-encryption-info.test b/llvm/test/tools/llvm-objcopy/MachO/strip-with-encryption-info.test index 19b06b1ec02c8..2b2bd670613de 100644 --- a/llvm/test/tools/llvm-objcopy/MachO/strip-with-encryption-info.test +++ b/llvm/test/tools/llvm-objcopy/MachO/strip-with-encryption-info.test @@ -1,13 +1,19 @@ # RUN: rm -rf %t && mkdir %t # RUN: yaml2obj %s -o %t/original # RUN: llvm-strip --strip-all %t/original -o %t/stripped -# RUN: llvm-readobj --macho-segment %t/stripped | FileCheck %s +# RUN: llvm-readobj --macho-segment --section-headers %t/stripped | FileCheck %s + +# CHECK-LABEL: Sections [ +# CHECK: Index: 0 +# CHECK-NEXT: Name: __text +# CHECK-NEXT: Segment: __TEXT +# CHECK: Offset: 16384 # CHECK-LABEL: Name: __PAGEZERO -# CHECK: fileoff: 16384 +# CHECK: fileoff: 0 # CHECK-LABEL: Name: __TEXT -# CHECK: fileoff: 16384 +# CHECK: fileoff: 0 # The YAML below is the following code # int main(int argc, char **argv) { return 0; } _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits