[llvm] [objcopy] Implement --weaken, --weaken-symbol(s) flags for MachO Object Files (PR #70560)

Dan Zimmerman via llvm-commits llvm-commits at lists.llvm.org
Sat Oct 28 10:56:51 PDT 2023


https://github.com/danzimm updated https://github.com/llvm/llvm-project/pull/70560

>From 9456cd865cbb5456bb7f99698619e62d9cf3e763 Mon Sep 17 00:00:00 2001
From: danzimm <daniel.zimmerman at me.com>
Date: Sat, 28 Oct 2023 12:50:19 -0500
Subject: [PATCH] [objcopy] Implement --weaken, --weaken-symbol(s) flags for
 MachO Object Files

---
 llvm/lib/ObjCopy/ConfigManager.cpp            |  4 +-
 llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp       |  8 ++
 .../tools/llvm-objcopy/MachO/weaken-all.s     | 36 ++++++++
 llvm/test/tools/llvm-objcopy/MachO/weaken.s   | 89 +++++++++++++++++++
 4 files changed, 135 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/tools/llvm-objcopy/MachO/weaken-all.s
 create mode 100644 llvm/test/tools/llvm-objcopy/MachO/weaken.s

diff --git a/llvm/lib/ObjCopy/ConfigManager.cpp b/llvm/lib/ObjCopy/ConfigManager.cpp
index 5b8e2f5dc2003af..bccb2903e62aeb4 100644
--- a/llvm/lib/ObjCopy/ConfigManager.cpp
+++ b/llvm/lib/ObjCopy/ConfigManager.cpp
@@ -34,13 +34,13 @@ Expected<const MachOConfig &> ConfigManager::getMachOConfig() const {
   if (!Common.SplitDWO.empty() || !Common.SymbolsPrefix.empty() ||
       !Common.AllocSectionsPrefix.empty() || !Common.KeepSection.empty() ||
       !Common.SymbolsToGlobalize.empty() || !Common.SymbolsToKeep.empty() ||
-      !Common.SymbolsToLocalize.empty() || !Common.SymbolsToWeaken.empty() ||
+      !Common.SymbolsToLocalize.empty() ||
       !Common.SymbolsToKeepGlobal.empty() || !Common.SectionsToRename.empty() ||
       !Common.UnneededSymbolsToRemove.empty() ||
       !Common.SetSectionAlignment.empty() || !Common.SetSectionFlags.empty() ||
       !Common.SetSectionType.empty() || Common.ExtractDWO ||
       Common.PreserveDates || Common.StripAllGNU || Common.StripDWO ||
-      Common.StripNonAlloc || Common.StripSections || Common.Weaken ||
+      Common.StripNonAlloc || Common.StripSections ||
       Common.DecompressDebugSections || Common.StripUnneeded ||
       Common.DiscardMode == DiscardType::Locals || !Common.SymbolsToAdd.empty())
     return createStringError(llvm::errc::invalid_argument,
diff --git a/llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp b/llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp
index 9d55c3d8a1a4868..491ec52c100f32c 100644
--- a/llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp
+++ b/llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp
@@ -94,6 +94,14 @@ static void updateAndRemoveSymbols(const CommonConfig &Config,
                                    const MachOConfig &MachOConfig,
                                    Object &Obj) {
   for (SymbolEntry &Sym : Obj.SymTable) {
+    // Weaken first to match ELFObjcopy behavior
+    bool IsExportedAndDefined =
+        Sym.n_type & llvm::MachO::N_EXT &&
+        (Sym.n_type & llvm::MachO::N_TYPE) != llvm::MachO::N_UNDF;
+    if (IsExportedAndDefined &&
+        (Config.Weaken || Config.SymbolsToWeaken.matches(Sym.Name)))
+      Sym.n_desc |= llvm::MachO::N_WEAK_DEF;
+
     auto I = Config.SymbolsToRename.find(Sym.Name);
     if (I != Config.SymbolsToRename.end())
       Sym.Name = std::string(I->getValue());
diff --git a/llvm/test/tools/llvm-objcopy/MachO/weaken-all.s b/llvm/test/tools/llvm-objcopy/MachO/weaken-all.s
new file mode 100644
index 000000000000000..740514f311eb5d5
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/MachO/weaken-all.s
@@ -0,0 +1,36 @@
+# REQUIRES: x86-registered-target
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos %s -o %t
+
+# RUN: llvm-objcopy --weaken %t %t2
+# RUN: llvm-readobj --symbols %t2 | FileCheck %s
+
+# CHECK:      Symbol {
+# CHECK-NEXT:   Name: _foo (1)
+# CHECK-NEXT:   Extern
+# CHECK-NEXT:   Type: Section (0xE)
+# CHECK-NEXT:   Section: __const (0x2)
+# CHECK-NEXT:   RefType: UndefinedNonLazy (0x0)
+# CHECK-NEXT:   Flags [ (0x80)
+# CHECK-NEXT:     WeakDef (0x80)
+# CHECK-NEXT:   ]
+# CHECK-NEXT:   Value: 0x0
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT:   Name: _func (6)
+# CHECK-NEXT:   Extern
+# CHECK-NEXT:   Type: Section (0xE)
+# CHECK-NEXT:   Section: __text (0x1)
+# CHECK-NEXT:   RefType: UndefinedNonLazy (0x0)
+# CHECK-NEXT:   Flags [ (0x80)
+# CHECK-NEXT:     WeakDef (0x80)
+# CHECK-NEXT:   ]
+# CHECK-NEXT:   Value: 0x0
+# CHECK-NEXT: }
+
+.globl _func
+_func:
+
+.section __TEXT,__const
+.globl _foo
+_foo:
diff --git a/llvm/test/tools/llvm-objcopy/MachO/weaken.s b/llvm/test/tools/llvm-objcopy/MachO/weaken.s
new file mode 100644
index 000000000000000..cb2b8672de33558
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/MachO/weaken.s
@@ -0,0 +1,89 @@
+# REQUIRES: x86-registered-target
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos %s -o %t
+
+# RUN: llvm-objcopy -W _func %t %t2
+# RUN: llvm-readobj --symbols %t2 | FileCheck %s -check-prefix=CHECK-1
+
+# CHECK-1:      Symbol {
+# CHECK-1-NEXT:   Name: _foo (1)
+# CHECK-1-NEXT:   Extern
+# CHECK-1-NEXT:   Type: Section (0xE)
+# CHECK-1-NEXT:   Section: __const (0x2)
+# CHECK-1-NEXT:   RefType: UndefinedNonLazy (0x0)
+# CHECK-1-NEXT:   Flags [ (0x0)
+# CHECK-1-NEXT:   ]
+# CHECK-1-NEXT:   Value: 0x0
+# CHECK-1-NEXT: }
+# CHECK-1-NEXT: Symbol {
+# CHECK-1-NEXT:   Name: _func (6)
+# CHECK-1-NEXT:   Extern
+# CHECK-1-NEXT:   Type: Section (0xE)
+# CHECK-1-NEXT:   Section: __text (0x1)
+# CHECK-1-NEXT:   RefType: UndefinedNonLazy (0x0)
+# CHECK-1-NEXT:   Flags [ (0x80)
+# CHECK-1-NEXT:     WeakDef (0x80)
+# CHECK-1-NEXT:   ]
+# CHECK-1-NEXT:   Value: 0x0
+# CHECK-1-NEXT: }
+
+# RUN: echo _foo > %t.rename.txt
+# RUN: echo _func >> %t.rename.txt
+# RUN: llvm-objcopy --weaken-symbols %t.rename.txt %t %t3
+# RUN: llvm-readobj --symbols %t3 | FileCheck %s -check-prefix=CHECK-2
+
+# CHECK-2:      Symbol {
+# CHECK-2-NEXT:   Name: _foo (1)
+# CHECK-2-NEXT:   Extern
+# CHECK-2-NEXT:   Type: Section (0xE)
+# CHECK-2-NEXT:   Section: __const (0x2)
+# CHECK-2-NEXT:   RefType: UndefinedNonLazy (0x0)
+# CHECK-2-NEXT:   Flags [ (0x80)
+# CHECK-2-NEXT:     WeakDef (0x80)
+# CHECK-2-NEXT:   ]
+# CHECK-2-NEXT:   Value: 0x0
+# CHECK-2-NEXT: }
+# CHECK-2-NEXT: Symbol {
+# CHECK-2-NEXT:   Name: _func (6)
+# CHECK-2-NEXT:   Extern
+# CHECK-2-NEXT:   Type: Section (0xE)
+# CHECK-2-NEXT:   Section: __text (0x1)
+# CHECK-2-NEXT:   RefType: UndefinedNonLazy (0x0)
+# CHECK-2-NEXT:   Flags [ (0x80)
+# CHECK-2-NEXT:     WeakDef (0x80)
+# CHECK-2-NEXT:   ]
+# CHECK-2-NEXT:   Value: 0x0
+# CHECK-2-NEXT: }
+
+## Verify --weaken-symbol plays nice with --redefine-sym
+# RUN: llvm-objcopy -W _foo --redefine-sym _foo=_bar %t %t4
+# RUN: llvm-readobj --symbols %t4 | FileCheck %s -check-prefix=CHECK-3
+
+# CHECK-3:      Symbol {
+# CHECK-3-NEXT:   Name: _bar (1)
+# CHECK-3-NEXT:   Extern
+# CHECK-3-NEXT:   Type: Section (0xE)
+# CHECK-3-NEXT:   Section: __const (0x2)
+# CHECK-3-NEXT:   RefType: UndefinedNonLazy (0x0)
+# CHECK-3-NEXT:   Flags [ (0x80)
+# CHECK-3-NEXT:     WeakDef (0x80)
+# CHECK-3-NEXT:   ]
+# CHECK-3-NEXT:   Value: 0x0
+# CHECK-3-NEXT: }
+# CHECK-3-NEXT: Symbol {
+# CHECK-3-NEXT:   Name: _func (6)
+# CHECK-3-NEXT:   Extern
+# CHECK-3-NEXT:   Type: Section (0xE)
+# CHECK-3-NEXT:   Section: __text (0x1)
+# CHECK-3-NEXT:   RefType: UndefinedNonLazy (0x0)
+# CHECK-3-NEXT:   Flags [ (0x0)
+# CHECK-3-NEXT:   ]
+# CHECK-3-NEXT:   Value: 0x0
+# CHECK-3-NEXT: }
+
+.globl _func
+_func:
+
+.section __TEXT,__const
+.globl _foo
+_foo:



More information about the llvm-commits mailing list