[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