-
Notifications
You must be signed in to change notification settings - Fork 13.4k
[llvm-objcopy] Apply encryptable offset to first segment, not section #130517
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Bug introduced llvm#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 checked the generated binaries after `llvm-objcopy` using `dyld_info`, as the bug report suggested. Fixes llvm#130472
@llvm/pr-subscribers-llvm-binary-utilities Author: Daniel Rodríguez Troitiño (drodriguez) ChangesBug introduced #120995. The LLD code calculates the "size" of the Mach-O headers, and then uses that size to place the segments, but the Besides the modified test checking for the right Fixes #130472 Full diff: https://github.com/llvm/llvm-project/pull/130517.diff 2 Files Affected:
diff --git a/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp b/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp
index d4eb6a9b9fc0b..91f73b59db1bd 100644
--- a/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp
+++ b/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp
@@ -116,11 +116,9 @@ 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 FirstSectExtraEncryptableOffset = O.EncryptionInfoCommandIndex.has_value();
for (LoadCommand &LC : O.LoadCommands) {
auto &MLC = LC.MachOLoadCommand;
StringRef Segname;
@@ -174,6 +172,10 @@ uint64_t MachOLayoutBuilder::layoutSegments() {
if (!Sec->hasValidOffset()) {
Sec->Offset = 0;
} else {
+ if (FirstSectExtraEncryptableOffset) {
+ SectOffset = alignToPowerOf2(SectOffset, PageSize);
+ FirstSectExtraEncryptableOffset = 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; }
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
Unfortunately, this is outside my minimal knowledge of Mach-O, so I'll leave it to another reviewer to look into. If nobody else shows up, let me know and I'll try adding some other possible reviewers. |
Sorry James. I though you were the other commenter in the other thread. My bad. @glandium do you mind checking if this was what was affecting your binary from #120995 ? For some reason the |
Not a problem. I'm involved in pretty much every change in llvm-objcopy ELF and generic code, but have also been heavily involved in some aspects of the other file formats, so confusion is entirely understandable. |
Applying this patch fixes the problem I had indeed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
…llvm#130517) Bug introduced llvm#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 llvm#130472 (cherry picked from commit 8413f4d)
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 atfileoff
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 afterllvm-objcopy
usingdyld_info
, as the bug report suggested.Fixes #130472