[llvm] 14f33c6 - [llvm-objcopy][mach-o] Fix section finding logic for object files (#127604)

via llvm-commits llvm-commits at lists.llvm.org
Sun Feb 23 11:18:01 PST 2025


Author: Dmitry Nechitaev
Date: 2025-02-23T11:17:58-08:00
New Revision: 14f33c6bc130495f591cebc8133089dff7a3e665

URL: https://github.com/llvm/llvm-project/commit/14f33c6bc130495f591cebc8133089dff7a3e665
DIFF: https://github.com/llvm/llvm-project/commit/14f33c6bc130495f591cebc8133089dff7a3e665.diff

LOG: [llvm-objcopy][mach-o] Fix section finding logic for object files (#127604)

Fix section finding logic for object files.
As by product, make --update-section functional when the input is an object file.

This PR fixes #127495

Added: 
    llvm/test/tools/llvm-objcopy/MachO/Inputs/macho_sections.s
    llvm/test/tools/llvm-objcopy/MachO/update-section-object.test

Modified: 
    llvm/docs/ReleaseNotes.md
    llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp
    llvm/test/tools/llvm-objcopy/MachO/update-section.test

Removed: 
    


################################################################################
diff  --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 75638d75e70f2..9203e22a9c886 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -146,6 +146,8 @@ Changes to the Debug Info
 Changes to the LLVM tools
 ---------------------------------
 
+* llvm-objcopy now supports the `--update-section` flag for intermediate Mach-O object files.
+
 Changes to LLDB
 ---------------------------------
 

diff  --git a/llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp b/llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp
index 682edffc84f34..cbc8e471b3090 100644
--- a/llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp
+++ b/llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp
@@ -360,6 +360,24 @@ static Error addSection(const NewSectionInfo &NewSection, Object &Obj) {
 static Expected<Section &> findSection(StringRef SecName, Object &O) {
   StringRef SegName;
   std::tie(SegName, SecName) = SecName.split(",");
+  // For compactness, intermediate object files (MH_OBJECT) contain
+  // only one segment in which all sections are placed.
+  // The static linker places each section in the named segment when building
+  // the final product (any file that is not of type MH_OBJECT).
+  //
+  // Source:
+  // https://math-atlas.sourceforge.net/devel/assembly/MachORuntime.pdf
+  // page 57
+  if (O.Header.FileType == MachO::HeaderFileType::MH_OBJECT) {
+    for (const auto& LC : O.LoadCommands)
+      for (const auto& Sec : LC.Sections)
+        if (Sec->Segname == SegName && Sec->Sectname == SecName)
+          return *Sec;
+
+    StringRef ErrMsg = "could not find section with name '%s' in '%s' segment";
+    return createStringError(errc::invalid_argument, ErrMsg.str().c_str(),
+                             SecName.str().c_str(), SegName.str().c_str());
+  }
   auto FoundSeg =
       llvm::find_if(O.LoadCommands, [SegName](const LoadCommand &LC) {
         return LC.getSegmentName() == SegName;

diff  --git a/llvm/test/tools/llvm-objcopy/MachO/Inputs/macho_sections.s b/llvm/test/tools/llvm-objcopy/MachO/Inputs/macho_sections.s
new file mode 100644
index 0000000000000..73f348017e57b
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/MachO/Inputs/macho_sections.s
@@ -0,0 +1,4 @@
+.section    __TEXT,__text
+  .space 64
+.section    __DATA,__storage
+  .space 128

diff  --git a/llvm/test/tools/llvm-objcopy/MachO/update-section-object.test b/llvm/test/tools/llvm-objcopy/MachO/update-section-object.test
new file mode 100644
index 0000000000000..2462536e17dfc
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/MachO/update-section-object.test
@@ -0,0 +1,47 @@
+# REQUIRES: aarch64-registered-target
+
+# RUN: llvm-mc -assemble -triple=arm64-apple-macos11 -filetype=obj %p/Inputs/macho_sections.s -o %t.o
+# RUN: llvm-otool -l %t.o | FileCheck %s --check-prefix=ORIG
+
+
+# RUN: llvm-objcopy %t.o --update-section __DATA,__storage=%p/Inputs/macho_sections.s %t.new.o
+# RUN: llvm-otool -l %t.new.o | FileCheck %s --check-prefix=UPDATED
+
+# ORIG:      cmd LC_SEGMENT_64
+# ORIG-NEXT: cmdsize 232
+# ORIG-NEXT: segname
+# ORIG-NEXT: vmaddr 0x0000000000000000
+# ORIG-NEXT: vmsize 0x00000000000000c0
+# ORIG-NEXT: fileoff 392
+# ORIG-NEXT: filesize 192
+# ORIG-NEXT: maxprot 0x00000007
+# ORIG-NEXT: initprot 0x00000007
+# ORIG-NEXT: nsects 2
+# ORIG-NEXT: flags 0x0
+
+# ORIG:      Section
+# ORIG:      sectname __storage
+# ORIG-NEXT: segname __DATA
+# ORIG-NEXT: addr 0x0000000000000040
+# ORIG-NEXT: size 0x0000000000000080
+
+
+### Make sure the file size and segment size have changed
+# UPDATED:      cmd LC_SEGMENT_64
+# UPDATED-NEXT: cmdsize 232
+# UPDATED-NEXT: segname
+# UPDATED-NEXT: vmaddr 0x0000000000000000
+# UPDATED-NEXT: vmsize 0x0000000000000090
+# UPDATED-NEXT: fileoff 392
+# UPDATED-NEXT: filesize 144
+# UPDATED-NEXT: maxprot 0x00000007
+# UPDATED-NEXT: initprot 0x00000007
+# UPDATED-NEXT: nsects 2
+# UPDATED-NEXT: flags 0x0
+
+# UPDATED:      Section
+# UPDATED:      sectname __storage
+# UPDATED-NEXT: segname __DATA
+# UPDATED-NEXT: addr 0x0000000000000040
+# UPDATED-NEXT: size 0x0000000000000050
+

diff  --git a/llvm/test/tools/llvm-objcopy/MachO/update-section.test b/llvm/test/tools/llvm-objcopy/MachO/update-section.test
index d9fb23d41474e..4ac7fc72d7f4d 100644
--- a/llvm/test/tools/llvm-objcopy/MachO/update-section.test
+++ b/llvm/test/tools/llvm-objcopy/MachO/update-section.test
@@ -16,7 +16,7 @@
 # RUN: not llvm-objcopy --update-section __TEXT,__text=%t.noexist %t /dev/null
 
 # RUN: not llvm-objcopy --update-section __NOEXIST,__text=%t.
diff  %t /dev/null 2>&1 | FileCheck %s --check-prefix=NO-SEGMENT
-# NO-SEGMENT: error: {{.*}}could not find segment with name '__NOEXIST'
+# NO-SEGMENT: error: {{.*}}could not find section with name '__text' in '__NOEXIST' segment
 
 # RUN: not llvm-objcopy --update-section __TEXT,__noexist=%t.
diff  %t /dev/null 2>&1 | FileCheck %s --check-prefix=NO-SECTION
 # NO-SECTION: error: {{.*}}could not find section with name '__noexist'


        


More information about the llvm-commits mailing list