[Win64EH] Write .pdata symbol relocations relative to the temporary begin symbol
authorMartin Storsjö <martin@martin.st>
Tue, 7 Sep 2021 11:56:43 +0000 (14:56 +0300)
committerMartin Storsjö <martin@martin.st>
Tue, 14 Sep 2021 08:05:37 +0000 (11:05 +0300)
Previously the relocations pointed at the public user facing,
possibly external symbol.

When the function itself is weak, that symbol may be overridden at
link time, pointing at another strong implementation of the same
function instead. In that case, there's two conflicting pdata entries
pointing at the same address, and the wrong unwind info might end up
used.

Both GCC/binutils and MSVC produce pdata pointing at internal static
symbols. (GCC/binutils point at the .text section just as LLVM does
after this change, MSVC points at special label type symbols with the
type IMAGE_SYM_CLASS_LABEL and names like '$LN4'.)

This fixes unwinding through an overridden "operator new" with a
statically linked C++ library in MinGW mode. (Building libc++ with
-ffunction-sections and linking with --gc-sections might avoid the
issue too.)

This makes the produced object files a little less user friendly
to debug, but with other recent improvements for llvm-readobj, the
unwind info debugging experience should be pretty much the same.

Differential Revision: https://reviews.llvm.org/D109651

llvm/lib/MC/MCWin64EH.cpp
llvm/test/MC/AArch64/seh.s
llvm/test/MC/COFF/seh-align1.s
llvm/test/MC/COFF/seh-align2.s
llvm/test/MC/COFF/seh-align3.s
llvm/test/MC/COFF/seh.s

index de1b0fd..7773d88 100644 (file)
@@ -144,8 +144,8 @@ static void EmitRuntimeFunction(MCStreamer &streamer,
   MCContext &context = streamer.getContext();
 
   streamer.emitValueToAlignment(4);
-  EmitSymbolRefWithOfs(streamer, info->Function, info->Begin);
-  EmitSymbolRefWithOfs(streamer, info->Function, info->End);
+  EmitSymbolRefWithOfs(streamer, info->Begin, info->Begin);
+  EmitSymbolRefWithOfs(streamer, info->Begin, info->End);
   streamer.emitValue(MCSymbolRefExpr::create(info->Symbol,
                                              MCSymbolRefExpr::VK_COFF_IMGREL32,
                                              context), 4);
@@ -1073,7 +1073,7 @@ static void ARM64EmitRuntimeFunction(MCStreamer &streamer,
   MCContext &context = streamer.getContext();
 
   streamer.emitValueToAlignment(4);
-  EmitSymbolRefWithOfs(streamer, info->Function, info->Begin);
+  EmitSymbolRefWithOfs(streamer, info->Begin, info->Begin);
   if (info->PackedInfo)
     streamer.emitInt32(info->PackedInfo);
   else
index 0da956c..0b7c2e6 100644 (file)
@@ -44,7 +44,7 @@
 // CHECK-NEXT:     0x28 IMAGE_REL_ARM64_ADDR32NB __C_specific_handler
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Section (5) .pdata {
-// CHECK-NEXT:     0x0 IMAGE_REL_ARM64_ADDR32NB func
+// CHECK-NEXT:     0x0 IMAGE_REL_ARM64_ADDR32NB .text
 // CHECK-NEXT:     0x4 IMAGE_REL_ARM64_ADDR32NB .xdata
 // CHECK-NEXT:   }
 // CHECK-NEXT: ]
index ead6a35..083b9a1 100644 (file)
@@ -28,8 +28,8 @@
 // CHECK-NEXT:       IMAGE_SCN_MEM_READ
 // CHECK-NEXT:     ]
 // CHECK:          Relocations [
-// CHECK-NEXT:       [[BeginDisp:0x[A-F0-9]+]] IMAGE_REL_AMD64_ADDR32NB smallFunc
-// CHECK-NEXT:       [[EndDisp:0x[A-F0-9]+]] IMAGE_REL_AMD64_ADDR32NB smallFunc
+// CHECK-NEXT:       [[BeginDisp:0x[A-F0-9]+]] IMAGE_REL_AMD64_ADDR32NB .text
+// CHECK-NEXT:       [[EndDisp:0x[A-F0-9]+]] IMAGE_REL_AMD64_ADDR32NB .text
 // CHECK-NEXT:       [[UnwindDisp:0x[A-F0-9]+]] IMAGE_REL_AMD64_ADDR32NB .xdata
 // CHECK-NEXT:     ]
 // CHECK:          SectionData (
index 31b9273..7981c18 100644 (file)
 // CHECK-NEXT:       IMAGE_SCN_MEM_READ
 // CHECK-NEXT:     ]
 // CHECK:          Relocations [
-// CHECK-NEXT:       [[BeginDisp:0x[A-F0-9]+]] IMAGE_REL_AMD64_ADDR32NB func
-// CHECK-NEXT:       [[EndDisp:0x[A-F0-9]+]] IMAGE_REL_AMD64_ADDR32NB func
+// CHECK-NEXT:       [[BeginDisp:0x[A-F0-9]+]] IMAGE_REL_AMD64_ADDR32NB .text
+// CHECK-NEXT:       [[EndDisp:0x[A-F0-9]+]] IMAGE_REL_AMD64_ADDR32NB .text
 // CHECK-NEXT:       [[UnwindDisp:0x[A-F0-9]+]] IMAGE_REL_AMD64_ADDR32NB .xdata
 // CHECK-NEXT:     ]
 // CHECK:          SectionData (
-// CHECK-NEXT:       0000: FCFFFFFF 05000000 00000000
+// CHECK-NEXT:       0000: 00000000 09000000 00000000
 // CHECK-NEXT:     )
 // CHECK-NEXT:   }
 // CHECK-NEXT: ]
 // CHECK:      UnwindInformation [
 // CHECK-NEXT:   RuntimeFunction {
-// CHECK-NEXT:     StartAddress: func {{(\+0x[A-F0-9]+ )?}}([[BeginDisp]])
+// CHECK-NEXT:     StartAddress: .text ([[BeginDisp]])
 // CHECK-NEXT:     EndAddress: func {{(\+0x[A-F0-9]+ )?}}([[EndDisp]])
 // CHECK-NEXT:     UnwindInfoAddress: .xdata {{(\+0x[A-F0-9]+ )?}}([[UnwindDisp]])
 // CHECK-NEXT:     UnwindInfo {
index cc57fbb..9b3e39d 100644 (file)
 // CHECK-NEXT:       IMAGE_SCN_MEM_READ
 // CHECK-NEXT:     ]
 // CHECK:          Relocations [
-// CHECK-NEXT:       [[BeginDisp:0x[A-F0-9]+]] IMAGE_REL_AMD64_ADDR32NB func
-// CHECK-NEXT:       [[EndDisp:0x[A-F0-9]+]] IMAGE_REL_AMD64_ADDR32NB func
+// CHECK-NEXT:       [[BeginDisp:0x[A-F0-9]+]] IMAGE_REL_AMD64_ADDR32NB .text
+// CHECK-NEXT:       [[EndDisp:0x[A-F0-9]+]] IMAGE_REL_AMD64_ADDR32NB .text
 // CHECK-NEXT:       [[UnwindDisp:0x[A-F0-9]+]] IMAGE_REL_AMD64_ADDR32NB .xdata
 // CHECK-NEXT:     ]
 // CHECK:          SectionData (
-// CHECK-NEXT:       0000: FCFFFFFF 05000000 00000000
+// CHECK-NEXT:       0000: 00000000 09000000 00000000
 // CHECK-NEXT:     )
 // CHECK-NEXT:   }
 // CHECK-NEXT: ]
 // CHECK:      UnwindInformation [
 // CHECK-NEXT:   RuntimeFunction {
-// CHECK-NEXT:     StartAddress: func {{(\+0x[A-F0-9]+ )?}}([[BeginDisp]])
+// CHECK-NEXT:     StartAddress: .text ([[BeginDisp]])
 // CHECK-NEXT:     EndAddress: func {{(\+0x[A-F0-9]+ )?}}([[EndDisp]])
 // CHECK-NEXT:     UnwindInfoAddress: .xdata {{(\+0x[A-F0-9]+ )?}}([[UnwindDisp]])
 // CHECK-NEXT:     UnwindInfo {
index 65bc79a..201cdb1 100644 (file)
 // CHECK-NEXT: Relocations [
 // CHECK-NEXT:   Section (4) .xdata {
 // CHECK-NEXT:     0x14 IMAGE_REL_AMD64_ADDR32NB __C_specific_handler
-// CHECK-NEXT:     0x20 IMAGE_REL_AMD64_ADDR32NB func
-// CHECK-NEXT:     0x24 IMAGE_REL_AMD64_ADDR32NB func
+// CHECK-NEXT:     0x20 IMAGE_REL_AMD64_ADDR32NB .text
+// CHECK-NEXT:     0x24 IMAGE_REL_AMD64_ADDR32NB .text
 // CHECK-NEXT:     0x28 IMAGE_REL_AMD64_ADDR32NB .xdata
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Section (5) .pdata {
-// CHECK-NEXT:     0x0 IMAGE_REL_AMD64_ADDR32NB func
-// CHECK-NEXT:     0x4 IMAGE_REL_AMD64_ADDR32NB func
+// CHECK-NEXT:     0x0 IMAGE_REL_AMD64_ADDR32NB .text
+// CHECK-NEXT:     0x4 IMAGE_REL_AMD64_ADDR32NB .text
 // CHECK-NEXT:     0x8 IMAGE_REL_AMD64_ADDR32NB .xdata
-// CHECK-NEXT:     0xC IMAGE_REL_AMD64_ADDR32NB func
-// CHECK-NEXT:     0x10 IMAGE_REL_AMD64_ADDR32NB func
+// CHECK-NEXT:     0xC IMAGE_REL_AMD64_ADDR32NB .text
+// CHECK-NEXT:     0x10 IMAGE_REL_AMD64_ADDR32NB .text
 // CHECK-NEXT:     0x14 IMAGE_REL_AMD64_ADDR32NB .xdata
-// CHECK-NEXT:     0x18 IMAGE_REL_AMD64_ADDR32NB smallFunc
-// CHECK-NEXT:     0x1C IMAGE_REL_AMD64_ADDR32NB smallFunc
+// CHECK-NEXT:     0x18 IMAGE_REL_AMD64_ADDR32NB .text
+// CHECK-NEXT:     0x1C IMAGE_REL_AMD64_ADDR32NB .text
 // CHECK-NEXT:     0x20 IMAGE_REL_AMD64_ADDR32NB .xdata
 // CHECK-NEXT:   }
 // CHECK-NEXT: ]