[llvm] r224738 - Fix Windows unwind info for functions in sections other than .text

Reid Kleckner reid at kleckner.net
Mon Dec 22 14:10:08 PST 2014


Author: rnk
Date: Mon Dec 22 16:10:08 2014
New Revision: 224738

URL: http://llvm.org/viewvc/llvm-project?rev=224738&view=rev
Log:
Fix Windows unwind info for functions in sections other than .text

Previously we assumed the section name had the form .text$foo, which is
what we used to do for inline functions. If the dollar wasn't present,
we'd put unwind data in the .pdata and .xdata sections for the main
.text section, which is incorrect.

Fixes PR22001.

Modified:
    llvm/trunk/lib/MC/MCWinEH.cpp
    llvm/trunk/test/MC/COFF/seh-section.s

Modified: llvm/trunk/lib/MC/MCWinEH.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCWinEH.cpp?rev=224738&r1=224737&r2=224738&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCWinEH.cpp (original)
+++ llvm/trunk/lib/MC/MCWinEH.cpp Mon Dec 22 16:10:08 2014
@@ -17,52 +17,45 @@
 
 namespace llvm {
 namespace WinEH {
-static StringRef getSectionSuffix(const MCSymbol *Function) {
-  if (!Function || !Function->isInSection())
-    return "";
-
-  const MCSection *FunctionSection = &Function->getSection();
-  if (const auto Section = dyn_cast<MCSectionCOFF>(FunctionSection)) {
-    StringRef Name = Section->getSectionName();
-    size_t Dollar = Name.find('$');
-    size_t Dot = Name.find('.', 1);
-
-    if (Dollar == StringRef::npos && Dot == StringRef::npos)
-      return "";
-    if (Dot == StringRef::npos)
-      return Name.substr(Dollar);
-    if (Dollar == StringRef::npos || Dot < Dollar)
-      return Name.substr(Dot);
-
-    return Name.substr(Dollar);
-  }
-
-  return "";
-}
 
+/// We can't have one section for all .pdata or .xdata because the Microsoft
+/// linker seems to want all code relocations to refer to the same object file
+/// section. If the code described is comdat, create a new comdat section
+/// associated with that comdat. If the code described is not in the main .text
+/// section, make a new section for it. Otherwise use the main unwind info
+/// section.
 static const MCSection *getUnwindInfoSection(
     StringRef SecName, const MCSectionCOFF *UnwindSec, const MCSymbol *Function,
     MCContext &Context) {
-  // If Function is in a COMDAT, get or create an unwind info section in that
-  // COMDAT group.
   if (Function && Function->isInSection()) {
+    // If Function is in a COMDAT, get or create an unwind info section in that
+    // COMDAT group.
     const MCSectionCOFF *FunctionSection =
         cast<MCSectionCOFF>(&Function->getSection());
     if (FunctionSection->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
       return Context.getAssociativeCOFFSection(
           UnwindSec, FunctionSection->getCOMDATSymbol());
     }
+
+    // If Function is in a section other than .text, create a new .pdata section.
+    // Otherwise use the plain .pdata section.
+    if (const auto *Section = dyn_cast<MCSectionCOFF>(FunctionSection)) {
+      StringRef CodeSecName = Section->getSectionName();
+      if (CodeSecName == ".text")
+        return UnwindSec;
+
+      if (CodeSecName.startswith(".text$"))
+        CodeSecName = CodeSecName.substr(6);
+
+      return Context.getCOFFSection(
+          (SecName + Twine('$') + CodeSecName).str(),
+          COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ,
+          SectionKind::getDataRel());
+    }
   }
 
-  // If Function is in a section other than .text, create a new .pdata section.
-  // Otherwise use the plain .pdata section.
-  StringRef Suffix = getSectionSuffix(Function);
-  if (Suffix.empty())
-    return UnwindSec;
-  return Context.getCOFFSection((SecName + Suffix).str(),
-                                COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
-                                COFF::IMAGE_SCN_MEM_READ,
-                                SectionKind::getDataRel());
+  return UnwindSec;
+
 }
 
 const MCSection *UnwindEmitter::getPDataSection(const MCSymbol *Function,

Modified: llvm/trunk/test/MC/COFF/seh-section.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/COFF/seh-section.s?rev=224738&r1=224737&r2=224738&view=diff
==============================================================================
--- llvm/trunk/test/MC/COFF/seh-section.s (original)
+++ llvm/trunk/test/MC/COFF/seh-section.s Mon Dec 22 16:10:08 2014
@@ -1,5 +1,7 @@
-// This test ensures that, if the section containing a function has a suffix
-// (e.g. .text$foo), its unwind info section also has a suffix (.xdata$foo).
+// This test ensures functions in custom sections get unwind info emitted in a
+// distinct .xdata section. Ideally we'd just emit a second .xdata section with
+// the same name and characteristics, but MC uniques sections by name and
+// characteristics, so that is not possible.
 // RUN: llvm-mc -filetype=obj -triple x86_64-pc-win32 %s | llvm-readobj -s -sd | FileCheck %s
 
 // CHECK:      Name: .xdata$foo
@@ -20,6 +22,44 @@
 // CHECK-NEXT:   0000: 01050200 05500402
 // CHECK-NEXT: )
 
+// CHECK:      Name: .xdata$.mytext
+// CHECK-NEXT: VirtualSize
+// CHECK-NEXT: VirtualAddress
+// CHECK-NEXT: RawDataSize: 8
+// CHECK-NEXT: PointerToRawData
+// CHECK-NEXT: PointerToRelocations
+// CHECK-NEXT: PointerToLineNumbers
+// CHECK-NEXT: RelocationCount: 0
+// CHECK-NEXT: LineNumberCount: 0
+// CHECK-NEXT: Characteristics [
+// CHECK-NEXT:   IMAGE_SCN_ALIGN_4BYTES
+// CHECK-NEXT:   IMAGE_SCN_CNT_INITIALIZED_DATA
+// CHECK-NEXT:   IMAGE_SCN_MEM_READ
+// CHECK-NEXT: ]
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT:   0000: 01050200 05500402
+// CHECK-NEXT: )
+
+// CHECK:      Name: .xdata
+// CHECK-NEXT: VirtualSize
+// CHECK-NEXT: VirtualAddress
+// CHECK-NEXT: RawDataSize: 8
+// CHECK-NEXT: PointerToRawData
+// CHECK-NEXT: PointerToRelocations
+// CHECK-NEXT: PointerToLineNumbers
+// CHECK-NEXT: RelocationCount: 0
+// CHECK-NEXT: LineNumberCount: 0
+// CHECK-NEXT: Characteristics [
+// CHECK-NEXT:   IMAGE_SCN_ALIGN_4BYTES
+// CHECK-NEXT:   IMAGE_SCN_CNT_INITIALIZED_DATA
+// CHECK-NEXT:   IMAGE_SCN_MEM_READ
+// CHECK-NEXT: ]
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT:   0000: 01050200 05500402
+// CHECK-NEXT: )
+
+
+
     .section .text$foo,"x"
     .globl foo
     .def foo; .scl 2; .type 32; .endef
@@ -28,6 +68,36 @@ foo:
     subq $8, %rsp
     .seh_stackalloc 8
     pushq %rbp
+    .seh_pushreg %rbp
+    .seh_endprologue
+    popq %rbp
+    addq $8, %rsp
+    ret
+    .seh_endproc
+
+    .section .mytext,"x"
+    .globl bar
+    .def bar; .scl 2; .type 32; .endef
+    .seh_proc bar
+bar:
+    subq $8, %rsp
+    .seh_stackalloc 8
+    pushq %rbp
+    .seh_pushreg %rbp
+    .seh_endprologue
+    popq %rbp
+    addq $8, %rsp
+    ret
+    .seh_endproc
+
+    .section .text
+    .globl baz
+    .def baz; .scl 2; .type 32; .endef
+    .seh_proc baz
+baz:
+    subq $8, %rsp
+    .seh_stackalloc 8
+    pushq %rbp
     .seh_pushreg %rbp
     .seh_endprologue
     popq %rbp





More information about the llvm-commits mailing list