[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
Thu Nov 2 19:51:06 PDT 2023
https://github.com/danzimm updated https://github.com/llvm/llvm-project/pull/70560
>From 92b03893b0d79d210854ac35ffbecc4f9467f3f9 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 | 100 ++++++++++++++++++
llvm/test/tools/llvm-objcopy/MachO/weaken.s | 89 ++++++++++++++++
4 files changed, 199 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..91500c2d9dd47d5 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 symbols 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..67244e85a2e6e5c
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/MachO/weaken-all.s
@@ -0,0 +1,100 @@
+# 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 --sort-symbols=name | FileCheck %s
+
+# CHECK: Symbols [
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: _global ({{[0-9]+}})
+# 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: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: _global_data ({{[0-9]+}})
+# 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: _local ({{[0-9]+}})
+# CHECK-NEXT: Type: Section (0xE)
+# CHECK-NEXT: Section: __text (0x1)
+# CHECK-NEXT: RefType: UndefinedNonLazy (0x0)
+# CHECK-NEXT: Flags [ (0x0)
+# CHECK-NEXT: ]
+# CHECK-NEXT: Value: 0x0
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: _local_data ({{[0-9]+}})
+# CHECK-NEXT: Type: Section (0xE)
+# CHECK-NEXT: Section: __const (0x2)
+# CHECK-NEXT: RefType: UndefinedNonLazy (0x0)
+# CHECK-NEXT: Flags [ (0x0)
+# CHECK-NEXT: ]
+# CHECK-NEXT: Value: 0x0
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: _weak ({{[0-9]+}})
+# 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: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: _weak_data ({{[0-9]+}})
+# 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: _weak_global ({{[0-9]+}})
+# 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: }
+# CHECK-NEXT: ]
+
+.globl _global
+_global:
+
+_local:
+
+.weak_definition _weak
+_weak:
+
+.weak_definition _weak_global
+.globl _weak_global
+_weak_global:
+
+.section __TEXT,__const
+.globl _global_data
+_global_data:
+_local_data:
+
+.weak_definition _weak_data
+_weak_data:
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..722d29fe497fece
--- /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.weaken.txt
+# RUN: echo _func >> %t.weaken.txt
+# RUN: llvm-objcopy --weaken-symbols %t.weaken.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