[llvm] [llvm-objcopy][MachO] Align __LINKEDIT entries to pointer size (PR #203680)

via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 12 23:54:28 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-binary-utilities

Author: Sungbin Jo (goranmoomin)

<details>
<summary>Changes</summary>

Align Mach-O __LINKEDIT entries to the target pointer size when building the tail layout. This matches the behavior of ld64 and lld-macho.

dyld on macOS 27 rejects loading dylibs with misaligned __LINKEDIT entries.

See #<!-- -->203678 for the motivation of this fix.

---

Patch is 23.83 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/203680.diff


6 Files Affected:

- (modified) llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp (+51-35) 
- (modified) llvm/lib/ObjCopy/MachO/MachOObject.h (+25) 
- (modified) llvm/lib/ObjCopy/MachO/MachOWriter.cpp (+12-12) 
- (modified) llvm/test/tools/llvm-objcopy/MachO/linkedit-order-1.test (+12-11) 
- (modified) llvm/test/tools/llvm-objcopy/MachO/linkedit-order-2.test (+9-8) 
- (modified) llvm/test/tools/llvm-objcopy/MachO/symbol-table.test (+2-2) 


``````````diff
diff --git a/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp b/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp
index 8660c903c617d..2f720454dc609 100644
--- a/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp
+++ b/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp
@@ -10,6 +10,7 @@
 #include "llvm/Support/Alignment.h"
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/ErrorHandling.h"
+#include <utility>
 
 using namespace llvm;
 using namespace llvm::objcopy::macho;
@@ -235,18 +236,20 @@ Error MachOLayoutBuilder::layoutTail(uint64_t Offset) {
          "Incorrect tail offset");
   Offset = std::max(Offset, HeaderSize + O.Header.SizeOfCmds);
 
+  const uint64_t LinkEditAlign = Is64Bit ? 8 : 4;
+
   // The exports trie can be in either LC_DYLD_INFO or in
   // LC_DYLD_EXPORTS_TRIE, but not both.
-  size_t DyldInfoExportsTrieSize = 0;
-  size_t DyldExportsTrieSize = 0;
+  uint64_t DyldInfoExportsTrieSize = 0;
+  uint64_t DyldExportsTrieSize = 0;
   for (const auto &LC : O.LoadCommands) {
     switch (LC.MachOLoadCommand.load_command_data.cmd) {
     case MachO::LC_DYLD_INFO:
     case MachO::LC_DYLD_INFO_ONLY:
-      DyldInfoExportsTrieSize = O.Exports.Trie.size();
+      DyldInfoExportsTrieSize = O.Exports.getSize(LinkEditAlign);
       break;
     case MachO::LC_DYLD_EXPORTS_TRIE:
-      DyldExportsTrieSize = O.Exports.Trie.size();
+      DyldExportsTrieSize = O.Exports.getSize(LinkEditAlign);
       break;
     default:
       break;
@@ -263,28 +266,42 @@ Error MachOLayoutBuilder::layoutTail(uint64_t Offset) {
   // trie, chained fixups, dyld exports trie, function starts, data-in-code,
   // symbol table, indirect symbol table, symbol table strings,
   // dylib codesign drs, and code signature.
-  auto updateOffset = [&Offset](size_t Size) {
+  auto updateOffset = [&Offset, LinkEditAlign](uint64_t Size) {
+    Offset = alignTo(Offset, LinkEditAlign);
     uint64_t PreviousOffset = Offset;
-    Offset += Size;
-    return PreviousOffset;
+    uint64_t PaddedSize = alignTo(Size, LinkEditAlign);
+    Offset += PaddedSize;
+    return std::make_pair(PreviousOffset, PaddedSize);
   };
 
-  uint64_t StartOfRebaseInfo = updateOffset(O.Rebases.Opcodes.size());
-  uint64_t StartOfBindingInfo = updateOffset(O.Binds.Opcodes.size());
-  uint64_t StartOfWeakBindingInfo = updateOffset(O.WeakBinds.Opcodes.size());
-  uint64_t StartOfLazyBindingInfo = updateOffset(O.LazyBinds.Opcodes.size());
-  uint64_t StartOfExportTrie = updateOffset(DyldInfoExportsTrieSize);
-  uint64_t StartOfChainedFixups = updateOffset(O.ChainedFixups.Data.size());
-  uint64_t StartOfDyldExportsTrie = updateOffset(DyldExportsTrieSize);
-  uint64_t StartOfFunctionStarts = updateOffset(O.FunctionStarts.Data.size());
-  uint64_t StartOfDataInCode = updateOffset(O.DataInCode.Data.size());
-  uint64_t StartOfLinkerOptimizationHint =
-      updateOffset(O.LinkerOptimizationHint.Data.size());
-  uint64_t StartOfSymbols = updateOffset(NListSize * O.SymTable.Symbols.size());
+  auto [StartOfRebaseInfo, RebaseInfoSize] =
+      updateOffset(O.Rebases.getSize(LinkEditAlign));
+  auto [StartOfBindingInfo, BindingInfoSize] =
+      updateOffset(O.Binds.getSize(LinkEditAlign));
+  auto [StartOfWeakBindingInfo, WeakBindingInfoSize] =
+      updateOffset(O.WeakBinds.getSize(LinkEditAlign));
+  auto [StartOfLazyBindingInfo, LazyBindingInfoSize] =
+      updateOffset(O.LazyBinds.getSize(LinkEditAlign));
+  auto [StartOfExportTrie, ExportTrieSize] =
+      updateOffset(DyldInfoExportsTrieSize);
+  auto [StartOfChainedFixups, ChainedFixupsSize] =
+      updateOffset(O.ChainedFixups.getSize(LinkEditAlign));
+  auto [StartOfDyldExportsTrie, DyldExportsTrieSizeOut] =
+      updateOffset(DyldExportsTrieSize);
+  auto [StartOfFunctionStarts, FunctionStartsSize] =
+      updateOffset(O.FunctionStarts.getSize(LinkEditAlign));
+  auto [StartOfDataInCode, DataInCodeSize] =
+      updateOffset(O.DataInCode.getSize(LinkEditAlign));
+  auto [StartOfLinkerOptimizationHint, LinkerOptimizationHintSize] =
+      updateOffset(O.LinkerOptimizationHint.getSize(LinkEditAlign));
+  uint64_t StartOfSymbols =
+      updateOffset(NListSize * O.SymTable.Symbols.size()).first;
   uint64_t StartOfIndirectSymbols =
-      updateOffset(sizeof(uint32_t) * O.IndirectSymTable.Symbols.size());
-  uint64_t StartOfSymbolStrings = updateOffset(StrTableBuilder.getSize());
-  uint64_t StartOfDylibCodeSignDRs = updateOffset(O.DylibCodeSignDRs.Data.size());
+      updateOffset(sizeof(uint32_t) * O.IndirectSymTable.Symbols.size()).first;
+  auto [StartOfSymbolStrings, SymbolStringsSize] =
+      updateOffset(StrTableBuilder.getSize());
+  auto [StartOfDylibCodeSignDRs, DylibCodeSignDRsSize] =
+      updateOffset(O.DylibCodeSignDRs.getSize(LinkEditAlign));
 
   uint64_t StartOfCodeSignature = Offset;
   uint32_t CodeSignatureSize = 0;
@@ -343,13 +360,13 @@ Error MachOLayoutBuilder::layoutTail(uint64_t Offset) {
       break;
     case MachO::LC_DYLIB_CODE_SIGN_DRS:
       MLC.linkedit_data_command_data.dataoff = StartOfDylibCodeSignDRs;
-      MLC.linkedit_data_command_data.datasize = O.DylibCodeSignDRs.Data.size();
+      MLC.linkedit_data_command_data.datasize = DylibCodeSignDRsSize;
       break;
     case MachO::LC_SYMTAB:
       MLC.symtab_command_data.symoff = StartOfSymbols;
       MLC.symtab_command_data.nsyms = O.SymTable.Symbols.size();
       MLC.symtab_command_data.stroff = StartOfSymbolStrings;
-      MLC.symtab_command_data.strsize = StrTableBuilder.getSize();
+      MLC.symtab_command_data.strsize = SymbolStringsSize;
       break;
     case MachO::LC_DYSYMTAB: {
       if (MLC.dysymtab_command_data.ntoc != 0 ||
@@ -368,42 +385,41 @@ Error MachOLayoutBuilder::layoutTail(uint64_t Offset) {
     }
     case MachO::LC_DATA_IN_CODE:
       MLC.linkedit_data_command_data.dataoff = StartOfDataInCode;
-      MLC.linkedit_data_command_data.datasize = O.DataInCode.Data.size();
+      MLC.linkedit_data_command_data.datasize = DataInCodeSize;
       break;
     case MachO::LC_LINKER_OPTIMIZATION_HINT:
       MLC.linkedit_data_command_data.dataoff = StartOfLinkerOptimizationHint;
-      MLC.linkedit_data_command_data.datasize =
-          O.LinkerOptimizationHint.Data.size();
+      MLC.linkedit_data_command_data.datasize = LinkerOptimizationHintSize;
       break;
     case MachO::LC_FUNCTION_STARTS:
       MLC.linkedit_data_command_data.dataoff = StartOfFunctionStarts;
-      MLC.linkedit_data_command_data.datasize = O.FunctionStarts.Data.size();
+      MLC.linkedit_data_command_data.datasize = FunctionStartsSize;
       break;
     case MachO::LC_DYLD_CHAINED_FIXUPS:
       MLC.linkedit_data_command_data.dataoff = StartOfChainedFixups;
-      MLC.linkedit_data_command_data.datasize = O.ChainedFixups.Data.size();
+      MLC.linkedit_data_command_data.datasize = ChainedFixupsSize;
       break;
     case MachO::LC_DYLD_EXPORTS_TRIE:
       MLC.linkedit_data_command_data.dataoff = StartOfDyldExportsTrie;
-      MLC.linkedit_data_command_data.datasize = DyldExportsTrieSize;
+      MLC.linkedit_data_command_data.datasize = DyldExportsTrieSizeOut;
       break;
     case MachO::LC_DYLD_INFO:
     case MachO::LC_DYLD_INFO_ONLY:
       MLC.dyld_info_command_data.rebase_off =
           O.Rebases.Opcodes.empty() ? 0 : StartOfRebaseInfo;
-      MLC.dyld_info_command_data.rebase_size = O.Rebases.Opcodes.size();
+      MLC.dyld_info_command_data.rebase_size = RebaseInfoSize;
       MLC.dyld_info_command_data.bind_off =
           O.Binds.Opcodes.empty() ? 0 : StartOfBindingInfo;
-      MLC.dyld_info_command_data.bind_size = O.Binds.Opcodes.size();
+      MLC.dyld_info_command_data.bind_size = BindingInfoSize;
       MLC.dyld_info_command_data.weak_bind_off =
           O.WeakBinds.Opcodes.empty() ? 0 : StartOfWeakBindingInfo;
-      MLC.dyld_info_command_data.weak_bind_size = O.WeakBinds.Opcodes.size();
+      MLC.dyld_info_command_data.weak_bind_size = WeakBindingInfoSize;
       MLC.dyld_info_command_data.lazy_bind_off =
           O.LazyBinds.Opcodes.empty() ? 0 : StartOfLazyBindingInfo;
-      MLC.dyld_info_command_data.lazy_bind_size = O.LazyBinds.Opcodes.size();
+      MLC.dyld_info_command_data.lazy_bind_size = LazyBindingInfoSize;
       MLC.dyld_info_command_data.export_off =
           O.Exports.Trie.empty() ? 0 : StartOfExportTrie;
-      MLC.dyld_info_command_data.export_size = DyldInfoExportsTrieSize;
+      MLC.dyld_info_command_data.export_size = ExportTrieSize;
       break;
     // Note that LC_ENCRYPTION_INFO.cryptoff despite its name and the comment in
     // <mach-o/loader.h> is not an offset in the binary file, instead, it is a
diff --git a/llvm/lib/ObjCopy/MachO/MachOObject.h b/llvm/lib/ObjCopy/MachO/MachOObject.h
index 86c6b120fa6c3..8ea5c01c466fe 100644
--- a/llvm/lib/ObjCopy/MachO/MachOObject.h
+++ b/llvm/lib/ObjCopy/MachO/MachOObject.h
@@ -13,6 +13,7 @@
 #include "llvm/BinaryFormat/MachO.h"
 #include "llvm/MC/StringTableBuilder.h"
 #include "llvm/ObjectYAML/DWARFYAML.h"
+#include "llvm/Support/Alignment.h"
 #include "llvm/Support/StringSaver.h"
 #include "llvm/Support/YAMLTraits.h"
 #include <cstdint>
@@ -213,6 +214,10 @@ struct RebaseInfo {
   // At the moment we do not parse this info (and it is simply copied over),
   // but the proper support will be added later.
   ArrayRef<uint8_t> Opcodes;
+
+  uint64_t getSize(uint64_t Alignment) const {
+    return alignTo(Opcodes.size(), Alignment);
+  }
 };
 
 /// The location of the bind info inside the binary is described by
@@ -229,6 +234,10 @@ struct BindInfo {
   // At the moment we do not parse this info (and it is simply copied over),
   // but the proper support will be added later.
   ArrayRef<uint8_t> Opcodes;
+
+  uint64_t getSize(uint64_t Alignment) const {
+    return alignTo(Opcodes.size(), Alignment);
+  }
 };
 
 /// The location of the weak bind info inside the binary is described by
@@ -247,6 +256,10 @@ struct WeakBindInfo {
   // At the moment we do not parse this info (and it is simply copied over),
   // but the proper support will be added later.
   ArrayRef<uint8_t> Opcodes;
+
+  uint64_t getSize(uint64_t Alignment) const {
+    return alignTo(Opcodes.size(), Alignment);
+  }
 };
 
 /// The location of the lazy bind info inside the binary is described by
@@ -260,6 +273,10 @@ struct WeakBindInfo {
 /// to lazy_bind_off to get the information on what to bind.
 struct LazyBindInfo {
   ArrayRef<uint8_t> Opcodes;
+
+  uint64_t getSize(uint64_t Alignment) const {
+    return alignTo(Opcodes.size(), Alignment);
+  }
 };
 
 /// The location of the export info inside the binary is described by
@@ -290,10 +307,18 @@ struct LazyBindInfo {
 /// edge points to.
 struct ExportInfo {
   ArrayRef<uint8_t> Trie;
+
+  uint64_t getSize(uint64_t Alignment) const {
+    return alignTo(Trie.size(), Alignment);
+  }
 };
 
 struct LinkData {
   ArrayRef<uint8_t> Data;
+
+  uint64_t getSize(uint64_t Alignment) const {
+    return alignTo(Data.size(), Alignment);
+  }
 };
 
 struct Object {
diff --git a/llvm/lib/ObjCopy/MachO/MachOWriter.cpp b/llvm/lib/ObjCopy/MachO/MachOWriter.cpp
index 07514dd2f8d6a..911e22927e559 100644
--- a/llvm/lib/ObjCopy/MachO/MachOWriter.cpp
+++ b/llvm/lib/ObjCopy/MachO/MachOWriter.cpp
@@ -55,29 +55,29 @@ size_t MachOWriter::totalSize() const {
         O.LoadCommands[*O.DyLdInfoCommandIndex]
             .MachOLoadCommand.dyld_info_command_data;
     if (DyLdInfoCommand.rebase_off) {
-      assert((DyLdInfoCommand.rebase_size == O.Rebases.Opcodes.size()) &&
+      assert((DyLdInfoCommand.rebase_size >= O.Rebases.Opcodes.size()) &&
              "Incorrect rebase opcodes size");
       Ends.push_back(DyLdInfoCommand.rebase_off + DyLdInfoCommand.rebase_size);
     }
     if (DyLdInfoCommand.bind_off) {
-      assert((DyLdInfoCommand.bind_size == O.Binds.Opcodes.size()) &&
+      assert((DyLdInfoCommand.bind_size >= O.Binds.Opcodes.size()) &&
              "Incorrect bind opcodes size");
       Ends.push_back(DyLdInfoCommand.bind_off + DyLdInfoCommand.bind_size);
     }
     if (DyLdInfoCommand.weak_bind_off) {
-      assert((DyLdInfoCommand.weak_bind_size == O.WeakBinds.Opcodes.size()) &&
+      assert((DyLdInfoCommand.weak_bind_size >= O.WeakBinds.Opcodes.size()) &&
              "Incorrect weak bind opcodes size");
       Ends.push_back(DyLdInfoCommand.weak_bind_off +
                      DyLdInfoCommand.weak_bind_size);
     }
     if (DyLdInfoCommand.lazy_bind_off) {
-      assert((DyLdInfoCommand.lazy_bind_size == O.LazyBinds.Opcodes.size()) &&
+      assert((DyLdInfoCommand.lazy_bind_size >= O.LazyBinds.Opcodes.size()) &&
              "Incorrect lazy bind opcodes size");
       Ends.push_back(DyLdInfoCommand.lazy_bind_off +
                      DyLdInfoCommand.lazy_bind_size);
     }
     if (DyLdInfoCommand.export_off) {
-      assert((DyLdInfoCommand.export_size == O.Exports.Trie.size()) &&
+      assert((DyLdInfoCommand.export_size >= O.Exports.Trie.size()) &&
              "Incorrect trie size");
       Ends.push_back(DyLdInfoCommand.export_off + DyLdInfoCommand.export_size);
     }
@@ -320,7 +320,7 @@ void MachOWriter::writeRebaseInfo() {
       O.LoadCommands[*O.DyLdInfoCommandIndex]
           .MachOLoadCommand.dyld_info_command_data;
   char *Out = Buf->getBufferStart() + DyLdInfoCommand.rebase_off;
-  assert((DyLdInfoCommand.rebase_size == O.Rebases.Opcodes.size()) &&
+  assert((DyLdInfoCommand.rebase_size >= O.Rebases.Opcodes.size()) &&
          "Incorrect rebase opcodes size");
   memcpy(Out, O.Rebases.Opcodes.data(), O.Rebases.Opcodes.size());
 }
@@ -332,7 +332,7 @@ void MachOWriter::writeBindInfo() {
       O.LoadCommands[*O.DyLdInfoCommandIndex]
           .MachOLoadCommand.dyld_info_command_data;
   char *Out = Buf->getBufferStart() + DyLdInfoCommand.bind_off;
-  assert((DyLdInfoCommand.bind_size == O.Binds.Opcodes.size()) &&
+  assert((DyLdInfoCommand.bind_size >= O.Binds.Opcodes.size()) &&
          "Incorrect bind opcodes size");
   memcpy(Out, O.Binds.Opcodes.data(), O.Binds.Opcodes.size());
 }
@@ -344,7 +344,7 @@ void MachOWriter::writeWeakBindInfo() {
       O.LoadCommands[*O.DyLdInfoCommandIndex]
           .MachOLoadCommand.dyld_info_command_data;
   char *Out = Buf->getBufferStart() + DyLdInfoCommand.weak_bind_off;
-  assert((DyLdInfoCommand.weak_bind_size == O.WeakBinds.Opcodes.size()) &&
+  assert((DyLdInfoCommand.weak_bind_size >= O.WeakBinds.Opcodes.size()) &&
          "Incorrect weak bind opcodes size");
   memcpy(Out, O.WeakBinds.Opcodes.data(), O.WeakBinds.Opcodes.size());
 }
@@ -356,7 +356,7 @@ void MachOWriter::writeLazyBindInfo() {
       O.LoadCommands[*O.DyLdInfoCommandIndex]
           .MachOLoadCommand.dyld_info_command_data;
   char *Out = Buf->getBufferStart() + DyLdInfoCommand.lazy_bind_off;
-  assert((DyLdInfoCommand.lazy_bind_size == O.LazyBinds.Opcodes.size()) &&
+  assert((DyLdInfoCommand.lazy_bind_size >= O.LazyBinds.Opcodes.size()) &&
          "Incorrect lazy bind opcodes size");
   memcpy(Out, O.LazyBinds.Opcodes.data(), O.LazyBinds.Opcodes.size());
 }
@@ -368,7 +368,7 @@ void MachOWriter::writeExportInfo() {
       O.LoadCommands[*O.DyLdInfoCommandIndex]
           .MachOLoadCommand.dyld_info_command_data;
   char *Out = Buf->getBufferStart() + DyLdInfoCommand.export_off;
-  assert((DyLdInfoCommand.export_size == O.Exports.Trie.size()) &&
+  assert((DyLdInfoCommand.export_size >= O.Exports.Trie.size()) &&
          "Incorrect export trie size");
   memcpy(Out, O.Exports.Trie.data(), O.Exports.Trie.size());
 }
@@ -398,7 +398,7 @@ void MachOWriter::writeLinkData(std::optional<size_t> LCIndex,
   const MachO::linkedit_data_command &LinkEditDataCommand =
       O.LoadCommands[*LCIndex].MachOLoadCommand.linkedit_data_command_data;
   char *Out = Buf->getBufferStart() + LinkEditDataCommand.dataoff;
-  assert((LinkEditDataCommand.datasize == LD.Data.size()) &&
+  assert((LinkEditDataCommand.datasize >= LD.Data.size()) &&
          "Incorrect data size");
   memcpy(Out, LD.Data.data(), LD.Data.size());
 }
@@ -575,7 +575,7 @@ void MachOWriter::writeExportsTrieData() {
       O.LoadCommands[*O.ExportsTrieCommandIndex]
           .MachOLoadCommand.linkedit_data_command_data;
   char *Out = Buf->getBufferStart() + ExportsTrieCmd.dataoff;
-  assert((ExportsTrieCmd.datasize == O.Exports.Trie.size()) &&
+  assert((ExportsTrieCmd.datasize >= O.Exports.Trie.size()) &&
          "Incorrect export trie size");
   memcpy(Out, O.Exports.Trie.data(), O.Exports.Trie.size());
 }
diff --git a/llvm/test/tools/llvm-objcopy/MachO/linkedit-order-1.test b/llvm/test/tools/llvm-objcopy/MachO/linkedit-order-1.test
index 4915f344c1e7e..1ca55ba46be74 100644
--- a/llvm/test/tools/llvm-objcopy/MachO/linkedit-order-1.test
+++ b/llvm/test/tools/llvm-objcopy/MachO/linkedit-order-1.test
@@ -14,24 +14,25 @@
 # CHECK: fileoff:         [[#LINKEDIT_FILEOFF:]]
 # CHECK: filesize:        [[#LINKEDIT_FILESIZE:]]
 
+## LINKEDIT entries are aligned to the target word size.
 # CHECK: cmd:             LC_DYLD_INFO_ONLY
-# CHECK: rebase_off:      [[#REBASE_OFF: LINKEDIT_FILEOFF]]
+# CHECK: rebase_off:      [[#REBASE_OFF: mul(div(LINKEDIT_FILEOFF + 7, 8), 8)]]
 # CHECK: rebase_size:     [[#REBASE_SIZE:]]
-# CHECK: bind_off:        [[#BIND_OFF: REBASE_OFF + REBASE_SIZE]]
+# CHECK: bind_off:        [[#BIND_OFF: mul(div(REBASE_OFF + REBASE_SIZE + 7, 8), 8)]]
 # CHECK: bind_size:       [[#BIND_SIZE:]]
-# CHECK: weak_bind_off:   [[#WEAK_BIND_OFF: BIND_OFF + BIND_SIZE]]
+# CHECK: weak_bind_off:   [[#WEAK_BIND_OFF: mul(div(BIND_OFF + BIND_SIZE + 7, 8), 8)]]
 # CHECK: weak_bind_size:  [[#WEAK_BIND_SIZE:]]
-# CHECK: lazy_bind_off:   [[#LAZY_BIND_OFF: WEAK_BIND_OFF + WEAK_BIND_SIZE]]
+# CHECK: lazy_bind_off:   [[#LAZY_BIND_OFF: mul(div(WEAK_BIND_OFF + WEAK_BIND_SIZE + 7, 8), 8)]]
 # CHECK: lazy_bind_size:  [[#LAZY_BIND_SIZE:]]
-# CHECK: export_off:      [[#EXPORTS_OFF:LAZY_BIND_OFF + LAZY_BIND_SIZE]]
+# CHECK: export_off:      [[#EXPORTS_OFF: mul(div(LAZY_BIND_OFF + LAZY_BIND_SIZE + 7, 8), 8)]]
 # CHECK: export_size:     [[#EXPORTS_SIZE:]]
 
 # CHECK: cmd:             LC_FUNCTION_STARTS
-# CHECK: dataoff:         [[#FUNCTION_STARTS_FILEOFF: EXPORTS_OFF + EXPORTS_SIZE]]
+# CHECK: dataoff:         [[#FUNCTION_STARTS_FILEOFF: mul(div(EXPORTS_OFF + EXPORTS_SIZE + 7, 8), 8)]]
 # CHECK: datasize:        [[#FUNCTION_STARTS_FILESIZE:]]
 
 # CHECK: cmd:             LC_DATA_IN_CODE
-# CHECK: dataoff:         [[#DATA_IN_CODE_FILEOFF: FUNCTION_STARTS_FILEOFF + FUNCTION_STARTS_FILESIZE]]
+# CHECK: dataoff:         [[#DATA_IN_CODE_FILEOFF: mul(div(FUNCTION_STARTS_FILEOFF + FUNCTION_STARTS_FILESIZE + 7, 8), 8)]]
 # CHECK: datasize:        [[#DATA_IN_CODE_FILESIZE:]]
 
 ## Jump over LC_CODE_SIGNATURE, which needs to be checked last
@@ -39,24 +40,24 @@
 # CHECK: --- !mach-o
 
 # CHECK: cmd:             LC_SYMTAB
-# CHECK: symoff:          [[#SYMTAB_SYMOFF: DATA_IN_CODE_FILEOFF + DATA_IN_CODE_FILESIZE]]
+# CHECK: symoff:          [[#SYMTAB_SYMOFF: mul(div(DATA_IN_CODE_FILEOFF + DATA_IN_CODE_FILESIZE + 7, 8), 8)]]
 # CHECK: nsyms:           [[#SYMTAB_NSYMS:]]
 
 ## Skip over the strings table offset/size (part of LC_SYMTAB) until next loop.
 
 # CHECK: cmd:             LC_DYSYMTAB
-# CHECK: indirectsymoff:  [[#DYSYMTAB_INDIRECTSYMOFF: SYMTAB_SYMOFF + mul(SYMTAB_NSYMS, 16)]]
+# CHECK: indirectsymoff:  [[#DYSYMTAB_INDIRECTSYMOFF: mul(div(SYMTAB_SYMOFF + mul(SYMTAB_NSYMS, 16) + 7, 8), 8)]]
 # CHECK: nindirectsyms:   [[#DYSYMTAB_NINDIRECTSYMS:]]
 
 # CHECK: --- !mach-o
 
 # CHECK: cmd:             LC_SYMTAB
-# CHECK: stroff:          [[#SYMTAB_STROFF: DYSYMTAB_INDIRECTSYMOFF + mul(DYSYMTAB_NINDIRECTSYMS, 4)]]
+# CHECK: stroff:          [[#SYMTAB_STROFF: mul(div(DYSYMTAB_INDIRECTSYMOFF + mul(DYSYMTAB_NINDIRECTSYMS, 4) + 7, 8), 8)]]
 # CHECK: strsize:         [[#SYMTAB_STRSIZE:]]
 
 # CHECK: cmd:             LC_CODE_SIGNATURE
 ## LC_CODE_SIGNATURE needs to be aligned to 16 bytes boundaries.
-# CHECK: dataoff:         [[#CODE_SIGNATURE_FILEOFF: mul(div(SYMTAB_STROFF + SYMTAB_STRSIZE + 8, 16), 16)]]
+# CHECK: dataoff:         [[#CODE_SIGNATURE_FILEOFF: mul(div(SYMTAB_STROFF + SYMTAB_STRSIZE + 15, 16), 16)]]
 # CHECK: datasize:        [[#CODE_SIGNATURE_FILESIZE:LINKEDIT_FILEOFF + LINKEDIT_FILESIZE - CODE_SIGNATURE_FILEOFF]]
 
 --- !mach-o
diff --git a/llvm/test/tools/llvm-objcopy/MachO/linkedit-order-2.test b/llvm/test/tools/llvm-objcopy/MachO/linkedit-order-2.test
index 0c5521ece0e44..3ed61e301d841 100644
--- a/llvm/test/tools/llvm-objcopy/MachO/linkedit-order-2.test
+++ b/llvm/test/tools/llvm-objcopy/MachO/linkedit-order-2.test
@@ -1...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/203680


More information about the llvm-commits mailing list