Skip to content

Commit 4f63a60

Browse files
[AArch64] Fix Arm64EC mangling with C++ symbols using MD5 mangling. (#160963)
In addition to the usual mangling formats, MSVC uses a special mangling format for very long symbols: instead of actually emitting the mangled name, it hashes the name, and uses the hash as the symbol. This doesn't match any of the usual forms, so it needs special handling. Fixes a crash/link error when using such symbols. (Unrelated to this patch, there's something weird about the way MSVC handles these symbols in Arm64EC mode: it looks like MSVC is computing a different hash compared to x64 MSVC, and clang. I think this is bug. Noting this here in case someone wants to compare MSVC vs. clang output.)
1 parent f265353 commit 4f63a60

File tree

3 files changed

+62
-0
lines changed

3 files changed

+62
-0
lines changed

llvm/lib/IR/Mangler.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,19 @@ std::optional<std::string> llvm::getArm64ECMangledFunctionName(StringRef Name) {
307307
if (Name.contains("$$h"))
308308
return std::nullopt;
309309

310+
// Handle MD5 mangled names, which use a slightly different rule from
311+
// other C++ manglings.
312+
//
313+
// A non-Arm64EC function:
314+
//
315+
// ??@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@
316+
//
317+
// An Arm64EC function:
318+
//
319+
// ??@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@$$h@
320+
if (Name.starts_with("??@") && Name.ends_with("@"))
321+
return (Name + "$$h@").str();
322+
310323
// Ask the demangler where we should insert "$$h".
311324
auto InsertIdx = getArm64ECInsertionPointInMangledName(Name);
312325
if (!InsertIdx)
@@ -324,6 +337,10 @@ llvm::getArm64ECDemangledFunctionName(StringRef Name) {
324337
if (Name[0] != '?')
325338
return std::nullopt;
326339

340+
// MD5 mangled name; see comment in getArm64ECMangledFunctionName.
341+
if (Name.starts_with("??@") && Name.ends_with("@$$h@"))
342+
return Name.drop_back(4).str();
343+
327344
// Drop the ARM64EC "$$h" tag.
328345
std::pair<StringRef, StringRef> Pair = Name.split("$$h");
329346
if (Pair.second.empty())

llvm/test/CodeGen/AArch64/arm64ec-exit-thunks.ll

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,41 @@ declare <8 x i16> @large_vector(<8 x i16> %0) nounwind;
563563
; CHECK-NEXT: .seh_endfunclet
564564
; CHECK-NEXT: .seh_endproc
565565

566+
declare void @"??@md5mangleaaaaaaaaaaaaaaaaaaaaaaa@"()
567+
; CHECK-LABEL: .def "??$exit_thunk@md5mangleaaaaaaaaaaaaaaaaaaaaaaa@$$h@";
568+
; CHECK-NEXT: .scl 2;
569+
; CHECK-NEXT: .type 32;
570+
; CHECK-NEXT: .endef
571+
; CHECK-NEXT: .section .wowthk$aa,"xr",discard,"??$exit_thunk@md5mangleaaaaaaaaaaaaaaaaaaaaaaa@$$h@"
572+
; CHECK-NEXT: .globl "??$exit_thunk@md5mangleaaaaaaaaaaaaaaaaaaaaaaa@$$h@" // -- Begin function ??$exit_thunk@md5mangleaaaaaaaaaaaaaaaaaaaaaaa@$$h@
573+
; CHECK-NEXT: .p2align 2
574+
; CHECK-NEXT: "??$exit_thunk@md5mangleaaaaaaaaaaaaaaaaaaaaaaa@$$h@": // @"??$exit_thunk@md5mangleaaaaaaaaaaaaaaaaaaaaaaa@$$h@"
575+
; CHECK-NEXT: .weak_anti_dep "??@md5mangleaaaaaaaaaaaaaaaaaaaaaaa@"
576+
; CHECK-NEXT: "??@md5mangleaaaaaaaaaaaaaaaaaaaaaaa@" = "??@md5mangleaaaaaaaaaaaaaaaaaaaaaaa@$$h@"
577+
; CHECK-NEXT: .weak_anti_dep "??@md5mangleaaaaaaaaaaaaaaaaaaaaaaa@$$h@"
578+
; CHECK-NEXT: "??@md5mangleaaaaaaaaaaaaaaaaaaaaaaa@$$h@" = "??$exit_thunk@md5mangleaaaaaaaaaaaaaaaaaaaaaaa@$$h@"
579+
; CHECK-NEXT: .seh_proc "??$exit_thunk@md5mangleaaaaaaaaaaaaaaaaaaaaaaa@$$h@"
580+
; CHECK-NEXT: // %bb.0:
581+
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
582+
; CHECK-NEXT: .seh_save_reg_x x30, 16
583+
; CHECK-NEXT: .seh_endprologue
584+
; CHECK-NEXT: adrp x8, __os_arm64x_check_icall
585+
; CHECK-NEXT: adrp x11, "??@md5mangleaaaaaaaaaaaaaaaaaaaaaaa@"
586+
; CHECK-NEXT: add x11, x11, :lo12:"??@md5mangleaaaaaaaaaaaaaaaaaaaaaaa@"
587+
; CHECK-NEXT: ldr x8, [x8, :lo12:__os_arm64x_check_icall]
588+
; CHECK-NEXT: adrp x10, $iexit_thunk$cdecl$v$v
589+
; CHECK-NEXT: add x10, x10, :lo12:$iexit_thunk$cdecl$v$v
590+
; CHECK-NEXT: blr x8
591+
; CHECK-NEXT: .seh_startepilogue
592+
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
593+
; CHECK-NEXT: .seh_save_reg_x x30, 16
594+
; CHECK-NEXT: .seh_endepilogue
595+
; CHECK-NEXT: br x11
596+
; CHECK-NEXT: .seh_endfunclet
597+
; CHECK-NEXT: .seh_endproc
598+
599+
600+
566601
; CHECK-LABEL: .section .hybmp$x,"yi"
567602
; CHECK-NEXT: .symidx "#func_caller"
568603
; CHECK-NEXT: .symidx $ientry_thunk$cdecl$v$v
@@ -633,6 +668,12 @@ declare <8 x i16> @large_vector(<8 x i16> %0) nounwind;
633668
; CHECK-NEXT: .symidx "#large_vector$exit_thunk"
634669
; CHECK-NEXT: .symidx large_vector
635670
; CHECK-NEXT: .word 0
671+
; CHECK-NEXT: .symidx "??@md5mangleaaaaaaaaaaaaaaaaaaaaaaa@"
672+
; CHECK-NEXT: .symidx $iexit_thunk$cdecl$v$v
673+
; CHECK-NEXT: .word 4
674+
; CHECK-NEXT: .symidx "??$exit_thunk@md5mangleaaaaaaaaaaaaaaaaaaaaaaa@$$h@"
675+
; CHECK-NEXT: .symidx "??@md5mangleaaaaaaaaaaaaaaaaaaaaaaa@"
676+
; CHECK-NEXT: .word 0
636677

637678
define void @func_caller() nounwind {
638679
call void @no_op()
@@ -649,5 +690,6 @@ define void @func_caller() nounwind {
649690
call %T2 @simple_struct(%T1 { i16 0 }, %T2 { i32 0, float 0.0 }, %T3 { i64 0, double 0.0 }, %T4 { i64 0, double 0.0, i8 0 })
650691
call <4 x i8> @small_vector(<4 x i8> <i8 0, i8 0, i8 0, i8 0>)
651692
call <8 x i16> @large_vector(<8 x i16> <i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>)
693+
call void @"??@md5mangleaaaaaaaaaaaaaaaaaaaaaaa@"()
652694
ret void
653695
}

llvm/unittests/IR/ManglerTest.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,9 @@ TEST(ManglerTest, Arm64EC) {
243243
// public: int __cdecl Wrapper<struct A>::GetValue(struct WW<struct
244244
// A>::Z)const
245245
"?GetValue@?$Wrapper@UA@@@@$$hQEBAHUZ@?$WW@UA@@@@@Z",
246+
247+
// MD5 symbol
248+
"??@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@$$h@",
246249
};
247250

248251
for (const auto &Arm64ECName : Arm64ECNames) {

0 commit comments

Comments
 (0)