Skip to content

Commit 0807846

Browse files
authored
[objcopy] Implement --weaken, --weaken-symbol(s) flags for Mach-O Object Files (llvm#70560)
This PR implements --weaken, --weaken-symbol(s) flags in llvm-objcopy for Mach-O. Test plan: ninja check-all
1 parent ad27848 commit 0807846

File tree

4 files changed

+199
-2
lines changed

4 files changed

+199
-2
lines changed

llvm/lib/ObjCopy/ConfigManager.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,13 @@ Expected<const MachOConfig &> ConfigManager::getMachOConfig() const {
3434
if (!Common.SplitDWO.empty() || !Common.SymbolsPrefix.empty() ||
3535
!Common.AllocSectionsPrefix.empty() || !Common.KeepSection.empty() ||
3636
!Common.SymbolsToGlobalize.empty() || !Common.SymbolsToKeep.empty() ||
37-
!Common.SymbolsToLocalize.empty() || !Common.SymbolsToWeaken.empty() ||
37+
!Common.SymbolsToLocalize.empty() ||
3838
!Common.SymbolsToKeepGlobal.empty() || !Common.SectionsToRename.empty() ||
3939
!Common.UnneededSymbolsToRemove.empty() ||
4040
!Common.SetSectionAlignment.empty() || !Common.SetSectionFlags.empty() ||
4141
!Common.SetSectionType.empty() || Common.ExtractDWO ||
4242
Common.PreserveDates || Common.StripAllGNU || Common.StripDWO ||
43-
Common.StripNonAlloc || Common.StripSections || Common.Weaken ||
43+
Common.StripNonAlloc || Common.StripSections ||
4444
Common.DecompressDebugSections || Common.StripUnneeded ||
4545
Common.DiscardMode == DiscardType::Locals || !Common.SymbolsToAdd.empty())
4646
return createStringError(llvm::errc::invalid_argument,

llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,14 @@ static void updateAndRemoveSymbols(const CommonConfig &Config,
9494
const MachOConfig &MachOConfig,
9595
Object &Obj) {
9696
for (SymbolEntry &Sym : Obj.SymTable) {
97+
// Weaken symbols first to match ELFObjcopy behavior.
98+
bool IsExportedAndDefined =
99+
(Sym.n_type & llvm::MachO::N_EXT) &&
100+
(Sym.n_type & llvm::MachO::N_TYPE) != llvm::MachO::N_UNDF;
101+
if (IsExportedAndDefined &&
102+
(Config.Weaken || Config.SymbolsToWeaken.matches(Sym.Name)))
103+
Sym.n_desc |= llvm::MachO::N_WEAK_DEF;
104+
97105
auto I = Config.SymbolsToRename.find(Sym.Name);
98106
if (I != Config.SymbolsToRename.end())
99107
Sym.Name = std::string(I->getValue());
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# REQUIRES: x86-registered-target
2+
3+
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos %s -o %t
4+
5+
# RUN: llvm-objcopy --weaken %t %t2
6+
# RUN: llvm-readobj --symbols %t2 --sort-symbols=name | FileCheck %s
7+
8+
# CHECK: Symbols [
9+
# CHECK-NEXT: Symbol {
10+
# CHECK-NEXT: Name: _global ({{[0-9]+}})
11+
# CHECK-NEXT: Extern
12+
# CHECK-NEXT: Type: Section (0xE)
13+
# CHECK-NEXT: Section: __text (0x1)
14+
# CHECK-NEXT: RefType: UndefinedNonLazy (0x0)
15+
# CHECK-NEXT: Flags [ (0x80)
16+
# CHECK-NEXT: WeakDef (0x80)
17+
# CHECK-NEXT: ]
18+
# CHECK-NEXT: Value: 0x0
19+
# CHECK-NEXT: }
20+
# CHECK-NEXT: Symbol {
21+
# CHECK-NEXT: Name: _global_data ({{[0-9]+}})
22+
# CHECK-NEXT: Extern
23+
# CHECK-NEXT: Type: Section (0xE)
24+
# CHECK-NEXT: Section: __const (0x2)
25+
# CHECK-NEXT: RefType: UndefinedNonLazy (0x0)
26+
# CHECK-NEXT: Flags [ (0x80)
27+
# CHECK-NEXT: WeakDef (0x80)
28+
# CHECK-NEXT: ]
29+
# CHECK-NEXT: Value: 0x0
30+
# CHECK-NEXT: }
31+
# CHECK-NEXT: Symbol {
32+
# CHECK-NEXT: Name: _local ({{[0-9]+}})
33+
# CHECK-NEXT: Type: Section (0xE)
34+
# CHECK-NEXT: Section: __text (0x1)
35+
# CHECK-NEXT: RefType: UndefinedNonLazy (0x0)
36+
# CHECK-NEXT: Flags [ (0x0)
37+
# CHECK-NEXT: ]
38+
# CHECK-NEXT: Value: 0x0
39+
# CHECK-NEXT: }
40+
# CHECK-NEXT: Symbol {
41+
# CHECK-NEXT: Name: _local_data ({{[0-9]+}})
42+
# CHECK-NEXT: Type: Section (0xE)
43+
# CHECK-NEXT: Section: __const (0x2)
44+
# CHECK-NEXT: RefType: UndefinedNonLazy (0x0)
45+
# CHECK-NEXT: Flags [ (0x0)
46+
# CHECK-NEXT: ]
47+
# CHECK-NEXT: Value: 0x0
48+
# CHECK-NEXT: }
49+
# CHECK-NEXT: Symbol {
50+
# CHECK-NEXT: Name: _weak ({{[0-9]+}})
51+
# CHECK-NEXT: Type: Section (0xE)
52+
# CHECK-NEXT: Section: __text (0x1)
53+
# CHECK-NEXT: RefType: UndefinedNonLazy (0x0)
54+
# CHECK-NEXT: Flags [ (0x80)
55+
# CHECK-NEXT: WeakDef (0x80)
56+
# CHECK-NEXT: ]
57+
# CHECK-NEXT: Value: 0x0
58+
# CHECK-NEXT: }
59+
# CHECK-NEXT: Symbol {
60+
# CHECK-NEXT: Name: _weak_data ({{[0-9]+}})
61+
# CHECK-NEXT: Type: Section (0xE)
62+
# CHECK-NEXT: Section: __const (0x2)
63+
# CHECK-NEXT: RefType: UndefinedNonLazy (0x0)
64+
# CHECK-NEXT: Flags [ (0x80)
65+
# CHECK-NEXT: WeakDef (0x80)
66+
# CHECK-NEXT: ]
67+
# CHECK-NEXT: Value: 0x0
68+
# CHECK-NEXT: }
69+
# CHECK-NEXT: Symbol {
70+
# CHECK-NEXT: Name: _weak_global ({{[0-9]+}})
71+
# CHECK-NEXT: Extern
72+
# CHECK-NEXT: Type: Section (0xE)
73+
# CHECK-NEXT: Section: __text (0x1)
74+
# CHECK-NEXT: RefType: UndefinedNonLazy (0x0)
75+
# CHECK-NEXT: Flags [ (0x80)
76+
# CHECK-NEXT: WeakDef (0x80)
77+
# CHECK-NEXT: ]
78+
# CHECK-NEXT: Value: 0x0
79+
# CHECK-NEXT: }
80+
# CHECK-NEXT: ]
81+
82+
.globl _global
83+
_global:
84+
85+
_local:
86+
87+
.weak_definition _weak
88+
_weak:
89+
90+
.weak_definition _weak_global
91+
.globl _weak_global
92+
_weak_global:
93+
94+
.section __TEXT,__const
95+
.globl _global_data
96+
_global_data:
97+
_local_data:
98+
99+
.weak_definition _weak_data
100+
_weak_data:
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# REQUIRES: x86-registered-target
2+
3+
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos %s -o %t
4+
5+
# RUN: llvm-objcopy -W _func %t %t2
6+
# RUN: llvm-readobj --symbols %t2 | FileCheck %s -check-prefix=CHECK-1
7+
8+
# CHECK-1: Symbol {
9+
# CHECK-1-NEXT: Name: _foo (1)
10+
# CHECK-1-NEXT: Extern
11+
# CHECK-1-NEXT: Type: Section (0xE)
12+
# CHECK-1-NEXT: Section: __const (0x2)
13+
# CHECK-1-NEXT: RefType: UndefinedNonLazy (0x0)
14+
# CHECK-1-NEXT: Flags [ (0x0)
15+
# CHECK-1-NEXT: ]
16+
# CHECK-1-NEXT: Value: 0x0
17+
# CHECK-1-NEXT: }
18+
# CHECK-1-NEXT: Symbol {
19+
# CHECK-1-NEXT: Name: _func (6)
20+
# CHECK-1-NEXT: Extern
21+
# CHECK-1-NEXT: Type: Section (0xE)
22+
# CHECK-1-NEXT: Section: __text (0x1)
23+
# CHECK-1-NEXT: RefType: UndefinedNonLazy (0x0)
24+
# CHECK-1-NEXT: Flags [ (0x80)
25+
# CHECK-1-NEXT: WeakDef (0x80)
26+
# CHECK-1-NEXT: ]
27+
# CHECK-1-NEXT: Value: 0x0
28+
# CHECK-1-NEXT: }
29+
30+
# RUN: echo _foo > %t.weaken.txt
31+
# RUN: echo _func >> %t.weaken.txt
32+
# RUN: llvm-objcopy --weaken-symbols %t.weaken.txt %t %t3
33+
# RUN: llvm-readobj --symbols %t3 | FileCheck %s -check-prefix=CHECK-2
34+
35+
# CHECK-2: Symbol {
36+
# CHECK-2-NEXT: Name: _foo (1)
37+
# CHECK-2-NEXT: Extern
38+
# CHECK-2-NEXT: Type: Section (0xE)
39+
# CHECK-2-NEXT: Section: __const (0x2)
40+
# CHECK-2-NEXT: RefType: UndefinedNonLazy (0x0)
41+
# CHECK-2-NEXT: Flags [ (0x80)
42+
# CHECK-2-NEXT: WeakDef (0x80)
43+
# CHECK-2-NEXT: ]
44+
# CHECK-2-NEXT: Value: 0x0
45+
# CHECK-2-NEXT: }
46+
# CHECK-2-NEXT: Symbol {
47+
# CHECK-2-NEXT: Name: _func (6)
48+
# CHECK-2-NEXT: Extern
49+
# CHECK-2-NEXT: Type: Section (0xE)
50+
# CHECK-2-NEXT: Section: __text (0x1)
51+
# CHECK-2-NEXT: RefType: UndefinedNonLazy (0x0)
52+
# CHECK-2-NEXT: Flags [ (0x80)
53+
# CHECK-2-NEXT: WeakDef (0x80)
54+
# CHECK-2-NEXT: ]
55+
# CHECK-2-NEXT: Value: 0x0
56+
# CHECK-2-NEXT: }
57+
58+
## Verify --weaken-symbol plays nice with --redefine-sym.
59+
# RUN: llvm-objcopy -W _foo --redefine-sym _foo=_bar %t %t4
60+
# RUN: llvm-readobj --symbols %t4 | FileCheck %s -check-prefix=CHECK-3
61+
62+
# CHECK-3: Symbol {
63+
# CHECK-3-NEXT: Name: _bar (1)
64+
# CHECK-3-NEXT: Extern
65+
# CHECK-3-NEXT: Type: Section (0xE)
66+
# CHECK-3-NEXT: Section: __const (0x2)
67+
# CHECK-3-NEXT: RefType: UndefinedNonLazy (0x0)
68+
# CHECK-3-NEXT: Flags [ (0x80)
69+
# CHECK-3-NEXT: WeakDef (0x80)
70+
# CHECK-3-NEXT: ]
71+
# CHECK-3-NEXT: Value: 0x0
72+
# CHECK-3-NEXT: }
73+
# CHECK-3-NEXT: Symbol {
74+
# CHECK-3-NEXT: Name: _func (6)
75+
# CHECK-3-NEXT: Extern
76+
# CHECK-3-NEXT: Type: Section (0xE)
77+
# CHECK-3-NEXT: Section: __text (0x1)
78+
# CHECK-3-NEXT: RefType: UndefinedNonLazy (0x0)
79+
# CHECK-3-NEXT: Flags [ (0x0)
80+
# CHECK-3-NEXT: ]
81+
# CHECK-3-NEXT: Value: 0x0
82+
# CHECK-3-NEXT: }
83+
84+
.globl _func
85+
_func:
86+
87+
.section __TEXT,__const
88+
.globl _foo
89+
_foo:

0 commit comments

Comments
 (0)