[llvm] [MachO] Preserve weak attributes on aliases (PR #219534)

via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 28 10:04:27 PDT 2026


https://github.com/AsakuraMizu created https://github.com/llvm/llvm-project/pull/219534

Supersedes #212001

Fixes #111321

1. Use `emitLinkage` for Mach-O aliases so weak aliases are emitted as public weak definitions.
2. `MachObjectWriter` derives an alias's `n_desc` from its aliasee, which drops weak-definition bits set on the alias itself. Preserve `N_WEAK_DEF` and `N_WEAK_REF` from the alias while leaving the existing aliasee-derived flags unchanged.

>From 6d628005b34f23b6c1e882b918531b9631f7e6e6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9C=9D=E5=80=89=E6=B0=B4=E5=B8=8C?= <mizuk1 at mzk1.dev>
Date: Fri, 28 Aug 2026 22:45:30 +0800
Subject: [PATCH] [MachO] Preserve weak attributes on aliases

---
 llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp    |  4 +-
 llvm/lib/MC/MachObjectWriter.cpp              |  6 +-
 llvm/test/CodeGen/AArch64/macho-weak-alias.ll | 26 ++++++
 llvm/test/MC/MachO/weak-alias.s               | 84 +++++++++++++++++++
 4 files changed, 118 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/CodeGen/AArch64/macho-weak-alias.ll
 create mode 100644 llvm/test/MC/MachO/weak-alias.s

diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 3d06677d1706b..9deb1b00c4dd9 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -2685,7 +2685,9 @@ void AsmPrinter::emitGlobalAlias(const Module &M, const GlobalAlias &GA) {
     return;
   }
 
-  if (GA.hasExternalLinkage() || !MAI.getWeakRefDirective())
+  if (MAI.isMachO())
+    emitLinkage(&GA, Name);
+  else if (GA.hasExternalLinkage() || !MAI.getWeakRefDirective())
     OutStreamer->emitSymbolAttribute(Name, MCSA_Global);
   else if (GA.hasWeakLinkage() || GA.hasLinkOnceLinkage())
     OutStreamer->emitSymbolAttribute(Name, MCSA_WeakReference);
diff --git a/llvm/lib/MC/MachObjectWriter.cpp b/llvm/lib/MC/MachObjectWriter.cpp
index 790f7595807b9..ab76d0f94c57d 100644
--- a/llvm/lib/MC/MachObjectWriter.cpp
+++ b/llvm/lib/MC/MachObjectWriter.cpp
@@ -443,7 +443,11 @@ void MachObjectWriter::writeNlist(MachSymbolData &MSD, const MCAssembler &Asm) {
   // The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc'
   // value.
   bool EncodeAsAltEntry = IsAlias && OrigSymbol.isAltEntry();
-  W.write<uint16_t>(Symbol->getEncodedFlags(EncodeAsAltEntry));
+  uint16_t Flags = Symbol->getEncodedFlags(EncodeAsAltEntry);
+  if (IsAlias)
+    Flags |= OrigSymbol.getEncodedFlags(false) &
+             (MachO::N_WEAK_DEF | MachO::N_WEAK_REF);
+  W.write<uint16_t>(Flags);
   if (is64Bit())
     W.write<uint64_t>(Address);
   else
diff --git a/llvm/test/CodeGen/AArch64/macho-weak-alias.ll b/llvm/test/CodeGen/AArch64/macho-weak-alias.ll
new file mode 100644
index 0000000000000..13c3f3ec6cd11
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/macho-weak-alias.ll
@@ -0,0 +1,26 @@
+; RUN: llc -mtriple=aarch64-apple-macosx13.0.0 %s -o - | FileCheck %s
+
+ at foo = internal global i32 0
+ at external_alias = alias i32, ptr @foo
+ at internal_alias = internal alias i32, ptr @foo
+ at weak_alias = weak alias i32, ptr @foo
+ at hidden_weak_alias = weak hidden alias i32, ptr @foo
+ at linkonce_alias = linkonce alias i32, ptr @foo
+ at auto_hide_alias = linkonce_odr unnamed_addr alias i32, ptr @foo
+
+; CHECK:      .globl _external_alias
+; CHECK-NEXT: _external_alias = _foo
+; CHECK:      _internal_alias = _foo
+; CHECK:      .globl _weak_alias
+; CHECK-NEXT: .weak_definition _weak_alias
+; CHECK-NEXT: _weak_alias = _foo
+; CHECK:      .globl _hidden_weak_alias
+; CHECK-NEXT: .weak_definition _hidden_weak_alias
+; CHECK-NEXT: .private_extern _hidden_weak_alias
+; CHECK-NEXT: _hidden_weak_alias = _foo
+; CHECK:      .globl _linkonce_alias
+; CHECK-NEXT: .weak_definition _linkonce_alias
+; CHECK-NEXT: _linkonce_alias = _foo
+; CHECK:      .globl _auto_hide_alias
+; CHECK-NEXT: .weak_def_can_be_hidden _auto_hide_alias
+; CHECK-NEXT: _auto_hide_alias = _foo
diff --git a/llvm/test/MC/MachO/weak-alias.s b/llvm/test/MC/MachO/weak-alias.s
new file mode 100644
index 0000000000000..076abc3d2df87
--- /dev/null
+++ b/llvm/test/MC/MachO/weak-alias.s
@@ -0,0 +1,84 @@
+// RUN: llvm-mc -triple x86_64-apple-macosx13.0.0 -filetype=obj %s -o - | llvm-readobj --symbols - | FileCheck %s
+
+.text
+_foo:
+  nop
+
+.globl _external
+_external = _foo
+
+.globl _weak
+.weak_definition _weak
+_weak = _foo
+
+.globl _auto
+.weak_def_can_be_hidden _auto
+_auto = _foo
+
+_local = _foo
+
+.globl _weak_target
+.weak_definition _weak_target
+_weak_target:
+  nop
+
+.globl _strong_to_weak
+_strong_to_weak = _weak_target
+
+// CHECK:      Name: _local
+// 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:      Name: _auto
+// CHECK-NEXT: Extern
+// CHECK-NEXT: Type: Section (0xE)
+// CHECK-NEXT: Section: __text (0x1)
+// CHECK-NEXT: RefType: UndefinedNonLazy (0x0)
+// CHECK-NEXT: Flags [ (0xC0)
+// CHECK-NEXT:   WeakDef (0x80)
+// CHECK-NEXT:   WeakRef (0x40)
+// CHECK-NEXT: ]
+// CHECK-NEXT: Value: 0x0
+
+// CHECK:      Name: _external
+// CHECK-NEXT: Extern
+// 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:      Name: _strong_to_weak
+// 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: 0x1
+
+// CHECK:      Name: _weak
+// 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:      Name: _weak_target
+// 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: 0x1



More information about the llvm-commits mailing list