Skip to content

[MC,COFF] Change how we handle section symbols #96459

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

MaskRay
Copy link
Member

@MaskRay MaskRay commented Jun 24, 2024

13a79bb (2017) unified BeginSymbol and
section symbol for ELF. This patch does the same for COFF.

  • In getCOFFSection, all sections now have a BeginSymbol (section
    symbol). We do not need a dummy symbol name when getBeginSymbol is
    needed (used by AsmParser::Run and DWARF generation).
  • Section symbols are in the global symbol table. call .text will
    reference the section symbol instead of an undefined symbol. This
    matches GNU assembler. Unlike GNU, redefining the section symbol will
    cause a "symbol 'foo0' is already defined" error (see
    section-sym-err.s).

Created using spr 1.3.5-bogner
@llvmbot
Copy link
Member

llvmbot commented Jun 24, 2024

@llvm/pr-subscribers-debuginfo
@llvm/pr-subscribers-lld
@llvm/pr-subscribers-backend-aarch64
@llvm/pr-subscribers-mc

@llvm/pr-subscribers-lld-coff

Author: Fangrui Song (MaskRay)

Changes

13a79bb (2017) unified BeginSymbol and
section symbol for ELF. This patch does the same for COFF.

  • In getCOFFSection, Now for all sections have a begin symbol (section
    symbol). We do not need a dummy symbol name when getBeginSymbol is
    needed (currently used by DWARF generation).
  • Section symbols and COMDAT symbols are now in MCAssembler::Symbols.
    In WinCOFFWriter::executePostLayoutBinding, defineSection no longer
    needs to define them. This change causes some symbol table
    differences.

Patch is 25.97 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/96459.diff

16 Files Affected:

  • (modified) lld/test/COFF/associative-comdat-mingw-weak.s (+1-1)
  • (modified) lld/test/COFF/build-id-sym.s (+1-1)
  • (modified) llvm/include/llvm/MC/MCContext.h (+5-4)
  • (modified) llvm/include/llvm/MC/MCWinCOFFStreamer.h (+1)
  • (modified) llvm/lib/MC/MCContext.cpp (+30-21)
  • (modified) llvm/lib/MC/MCObjectFileInfo.cpp (+15-20)
  • (modified) llvm/lib/MC/MCWinCOFFStreamer.cpp (+5)
  • (modified) llvm/lib/MC/WinCOFFObjectWriter.cpp (+39-25)
  • (modified) llvm/test/CodeGen/AArch64/arm64ec-symbols.ll (+7-7)
  • (modified) llvm/test/DebugInfo/X86/InlinedFnLocalVar.ll (+1-1)
  • (modified) llvm/test/DebugInfo/X86/ref_addr_relocation.ll (+1-1)
  • (modified) llvm/test/MC/AArch64/seh-large-func-multi-epilog.s (+4-4)
  • (modified) llvm/test/MC/AArch64/seh-large-func.s (+10-10)
  • (modified) llvm/test/MC/COFF/section-comdat-conflict.s (+2-2)
  • (modified) llvm/test/MC/COFF/section-comdat-conflict2.s (+2-2)
  • (modified) llvm/test/MC/COFF/section-comdat.s (+16-16)
diff --git a/lld/test/COFF/associative-comdat-mingw-weak.s b/lld/test/COFF/associative-comdat-mingw-weak.s
index 80c738b436be4..4341cd9cee5af 100644
--- a/lld/test/COFF/associative-comdat-mingw-weak.s
+++ b/lld/test/COFF/associative-comdat-mingw-weak.s
@@ -28,7 +28,7 @@
 # SYMBOL-NEXT:    StorageClass: WeakExternal (0x69)
 # SYMBOL-NEXT:    AuxSymbolCount: 1
 # SYMBOL-NEXT:    AuxWeakExternal {
-# SYMBOL-NEXT:      Linked: .weak.foo.default.main (19)
+# SYMBOL-NEXT:      Linked: .weak.foo.default.main (17)
 # SYMBOL-NEXT:      Search: Alias (0x3)
 # SYMBOL-NEXT:    }
 # SYMBOL-NEXT:  }
diff --git a/lld/test/COFF/build-id-sym.s b/lld/test/COFF/build-id-sym.s
index faed7bc40fd06..938d80553bf1b 100644
--- a/lld/test/COFF/build-id-sym.s
+++ b/lld/test/COFF/build-id-sym.s
@@ -6,7 +6,7 @@
 # Check __buildid points to 0x14000203c which is after the signature RSDS.
 
 # CHECK:      SYMBOL TABLE:
-# CHECK-NEXT: 0x0000003c __buildid
+# CHECK:      0x0000003c __buildid
 # CHECK:      Contents of section .rdata:
 # CHECK-NEXT:  140002000
 # CHECK-NEXT:  140002010
diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index 69a20587eecfb..822a062f56d37 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -351,6 +351,9 @@ class MCContext {
   MCSymbol *getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal,
                                               unsigned Instance);
 
+  template <typename Symbol>
+  Symbol *getOrCreateSectionSymbol(StringRef Section);
+
   MCSectionELF *createELFSectionImpl(StringRef Section, unsigned Type,
                                      unsigned Flags, unsigned EntrySize,
                                      const MCSymbolELF *Group, bool IsComdat,
@@ -604,11 +607,9 @@ class MCContext {
 
   MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics,
                                 StringRef COMDATSymName, int Selection,
-                                unsigned UniqueID = GenericSectionID,
-                                const char *BeginSymName = nullptr);
+                                unsigned UniqueID = GenericSectionID);
 
-  MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics,
-                                const char *BeginSymName = nullptr);
+  MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics);
 
   /// Gets or creates a section equivalent to Sec that is associated with the
   /// section containing KeySym. For example, to create a debug info section
diff --git a/llvm/include/llvm/MC/MCWinCOFFStreamer.h b/llvm/include/llvm/MC/MCWinCOFFStreamer.h
index 0d346871df821..893a70f74ee3b 100644
--- a/llvm/include/llvm/MC/MCWinCOFFStreamer.h
+++ b/llvm/include/llvm/MC/MCWinCOFFStreamer.h
@@ -40,6 +40,7 @@ class MCWinCOFFStreamer : public MCObjectStreamer {
   /// \{
 
   void initSections(bool NoExecStack, const MCSubtargetInfo &STI) override;
+  void changeSection(MCSection *Section, uint32_t Subsection = 0) override;
   void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
   void emitAssemblerFlag(MCAssemblerFlag Flag) override;
   void emitThumbFunc(MCSymbol *Func) override;
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index 36603d06c2a29..141e2792a5ad4 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -491,14 +491,10 @@ MCSectionMachO *MCContext::getMachOSection(StringRef Segment, StringRef Section,
   return Ret;
 }
 
-MCSectionELF *MCContext::createELFSectionImpl(StringRef Section, unsigned Type,
-                                              unsigned Flags,
-                                              unsigned EntrySize,
-                                              const MCSymbolELF *Group,
-                                              bool Comdat, unsigned UniqueID,
-                                              const MCSymbolELF *LinkedToSym) {
-  MCSymbolELF *R;
-  MCSymbolTableEntry &SymEntry = getSymbolTableEntry(Section);
+template <typename Symbol>
+Symbol *MCContext::getOrCreateSectionSymbol(StringRef Section) {
+  Symbol *R;
+  auto &SymEntry = getSymbolTableEntry(Section);
   MCSymbol *Sym = SymEntry.second.Symbol;
   // A section symbol can not redefine regular symbols. There may be multiple
   // sections with the same name, in which case the first such section wins.
@@ -506,13 +502,23 @@ MCSectionELF *MCContext::createELFSectionImpl(StringRef Section, unsigned Type,
       (!Sym->isInSection() || Sym->getSection().getBeginSymbol() != Sym))
     reportError(SMLoc(), "invalid symbol redefinition");
   if (Sym && Sym->isUndefined()) {
-    R = cast<MCSymbolELF>(Sym);
+    R = cast<Symbol>(Sym);
   } else {
     SymEntry.second.Used = true;
-    R = new (&SymEntry, *this) MCSymbolELF(&SymEntry, /*isTemporary*/ false);
+    R = new (&SymEntry, *this) Symbol(&SymEntry, /*isTemporary=*/false);
     if (!Sym)
       SymEntry.second.Symbol = R;
   }
+  return R;
+}
+
+MCSectionELF *MCContext::createELFSectionImpl(StringRef Section, unsigned Type,
+                                              unsigned Flags,
+                                              unsigned EntrySize,
+                                              const MCSymbolELF *Group,
+                                              bool Comdat, unsigned UniqueID,
+                                              const MCSymbolELF *LinkedToSym) {
+  auto *R = getOrCreateSectionSymbol<MCSymbolELF>(Section);
   R->setBinding(ELF::STB_LOCAL);
   R->setType(ELF::STT_SECTION);
 
@@ -681,12 +687,19 @@ MCSectionGOFF *MCContext::getGOFFSection(StringRef Section, SectionKind Kind,
 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
                                          unsigned Characteristics,
                                          StringRef COMDATSymName, int Selection,
-                                         unsigned UniqueID,
-                                         const char *BeginSymName) {
+                                         unsigned UniqueID) {
   MCSymbol *COMDATSymbol = nullptr;
   if (!COMDATSymName.empty()) {
     COMDATSymbol = getOrCreateSymbol(COMDATSymName);
     COMDATSymName = COMDATSymbol->getName();
+    // A non-associative COMDAT is considered to define the COMDAT symbol. Check
+    // the redefinition error.
+    if (Selection != COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE && COMDATSymbol &&
+        COMDATSymbol->isDefined() &&
+        (!COMDATSymbol->isInSection() ||
+         cast<MCSectionCOFF>(COMDATSymbol->getSection()).getCOMDATSymbol() !=
+             COMDATSymbol))
+      reportError(SMLoc(), "invalid symbol redefinition");
   }
 
   // Do the lookup, if we have a hit, return it.
@@ -696,23 +709,19 @@ MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
   if (!IterBool.second)
     return Iter->second;
 
-  MCSymbol *Begin = nullptr;
-  if (BeginSymName)
-    Begin = createTempSymbol(BeginSymName, false);
-
   StringRef CachedName = Iter->first.SectionName;
+  MCSymbol *Begin = getOrCreateSectionSymbol<MCSymbolCOFF>(Section);
   MCSectionCOFF *Result = new (COFFAllocator.Allocate()) MCSectionCOFF(
       CachedName, Characteristics, COMDATSymbol, Selection, Begin);
   Iter->second = Result;
-  allocInitialFragment(*Result);
+  auto *F = allocInitialFragment(*Result);
+  Begin->setFragment(F);
   return Result;
 }
 
 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
-                                         unsigned Characteristics,
-                                         const char *BeginSymName) {
-  return getCOFFSection(Section, Characteristics, "", 0, GenericSectionID,
-                        BeginSymName);
+                                         unsigned Characteristics) {
+  return getCOFFSection(Section, Characteristics, "", 0, GenericSectionID);
 }
 
 MCSectionCOFF *MCContext::getAssociativeCOFFSection(MCSectionCOFF *Sec,
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index daa996311d1cf..7a2b43a954b10 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -611,24 +611,21 @@ void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
                                        COFF::IMAGE_SCN_MEM_READ));
 
   DwarfAbbrevSection = Ctx->getCOFFSection(
-      ".debug_abbrev",
-      COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
-          COFF::IMAGE_SCN_MEM_READ,
-      "section_abbrev");
+      ".debug_abbrev", COFF::IMAGE_SCN_MEM_DISCARDABLE |
+                           COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+                           COFF::IMAGE_SCN_MEM_READ);
   DwarfInfoSection = Ctx->getCOFFSection(
-      ".debug_info",
-      COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
-          COFF::IMAGE_SCN_MEM_READ,
-      "section_info");
+      ".debug_info", COFF::IMAGE_SCN_MEM_DISCARDABLE |
+                         COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+                         COFF::IMAGE_SCN_MEM_READ);
   DwarfLineSection = Ctx->getCOFFSection(
       ".debug_line", COFF::IMAGE_SCN_MEM_DISCARDABLE |
                          COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
                          COFF::IMAGE_SCN_MEM_READ);
   DwarfLineStrSection = Ctx->getCOFFSection(
-      ".debug_line_str",
-      COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
-          COFF::IMAGE_SCN_MEM_READ,
-      "section_line_str");
+      ".debug_line_str", COFF::IMAGE_SCN_MEM_DISCARDABLE |
+                             COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+                             COFF::IMAGE_SCN_MEM_READ);
   DwarfFrameSection = Ctx->getCOFFSection(
       ".debug_frame", COFF::IMAGE_SCN_MEM_DISCARDABLE |
                           COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
@@ -738,19 +735,17 @@ void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
                           COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
                           COFF::IMAGE_SCN_MEM_READ);
   DwarfAccelNamesSection = Ctx->getCOFFSection(
-      ".apple_names",
-      COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
-          COFF::IMAGE_SCN_MEM_READ,
-      "names_begin");
+      ".apple_names", COFF::IMAGE_SCN_MEM_DISCARDABLE |
+                          COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+                          COFF::IMAGE_SCN_MEM_READ);
   DwarfAccelNamespaceSection = Ctx->getCOFFSection(
       ".apple_namespaces", COFF::IMAGE_SCN_MEM_DISCARDABLE |
                                COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
                                COFF::IMAGE_SCN_MEM_READ);
   DwarfAccelTypesSection = Ctx->getCOFFSection(
-      ".apple_types",
-      COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
-          COFF::IMAGE_SCN_MEM_READ,
-      "types_begin");
+      ".apple_types", COFF::IMAGE_SCN_MEM_DISCARDABLE |
+                          COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+                          COFF::IMAGE_SCN_MEM_READ);
   DwarfAccelObjCSection = Ctx->getCOFFSection(
       ".apple_objc", COFF::IMAGE_SCN_MEM_DISCARDABLE |
                          COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
diff --git a/llvm/lib/MC/MCWinCOFFStreamer.cpp b/llvm/lib/MC/MCWinCOFFStreamer.cpp
index 634524d4df6fe..ad0152eff8fda 100644
--- a/llvm/lib/MC/MCWinCOFFStreamer.cpp
+++ b/llvm/lib/MC/MCWinCOFFStreamer.cpp
@@ -81,6 +81,11 @@ void MCWinCOFFStreamer::initSections(bool NoExecStack,
   switchSection(getContext().getObjectFileInfo()->getTextSection());
 }
 
+void MCWinCOFFStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
+  changeSectionImpl(Section, Subsection);
+  getAssembler().registerSymbol(*Section->getBeginSymbol());
+}
+
 void MCWinCOFFStreamer::emitLabel(MCSymbol *S, SMLoc Loc) {
   auto *Symbol = cast<MCSymbolCOFF>(S);
   MCObjectStreamer::emitLabel(Symbol, Loc);
diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp
index e5925586d99e6..51c9d4e4ccdc9 100644
--- a/llvm/lib/MC/WinCOFFObjectWriter.cpp
+++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp
@@ -144,6 +144,7 @@ class WinCOFFWriter {
   // Maps used during object file creation.
   section_map SectionMap;
   symbol_map SymbolMap;
+  DenseSet<StringRef> ComdatSymSet;
 
   symbol_list WeakDefaults;
 
@@ -322,27 +323,16 @@ static uint32_t getAlignment(const MCSectionCOFF &Sec) {
 void WinCOFFWriter::defineSection(const MCSectionCOFF &MCSec,
                                   const MCAsmLayout &Layout) {
   COFFSection *Section = createSection(MCSec.getName());
-  COFFSymbol *Symbol = createSymbol(MCSec.getName());
-  Section->Symbol = Symbol;
-  Symbol->Section = Section;
-  Symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_STATIC;
-
-  // Create a COMDAT symbol if needed.
+  // Check whether the COMDAT symbol has been reused.
   if (MCSec.getSelection() != COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
     if (const MCSymbol *S = MCSec.getCOMDATSymbol()) {
-      COFFSymbol *COMDATSymbol = GetOrCreateCOFFSymbol(S);
-      if (COMDATSymbol->Section)
-        report_fatal_error("two sections have the same comdat");
-      COMDATSymbol->Section = Section;
+      if (!ComdatSymSet.insert(S->getName()).second)
+        Layout.getAssembler().getContext().reportError(
+            SMLoc(),
+            Twine("COMDAT symbol '" + S->getName() + "' used by two sections"));
     }
   }
 
-  // In this case the auxiliary symbol is a Section Definition.
-  Symbol->Aux.resize(1);
-  Symbol->Aux[0] = {};
-  Symbol->Aux[0].AuxType = ATSectionDefinition;
-  Symbol->Aux[0].Aux.SectionDefinition.Selection = MCSec.getSelection();
-
   // Set section alignment.
   Section->Header.Characteristics = MCSec.getCharacteristics();
   Section->Header.Characteristics |= getAlignment(MCSec);
@@ -401,10 +391,25 @@ void WinCOFFWriter::DefineSymbol(const MCSymbol &MCSym, MCAssembler &Assembler,
   COFFSymbol *Sym = GetOrCreateCOFFSymbol(&MCSym);
   const MCSymbol *Base = Layout.getBaseSymbol(MCSym);
   COFFSection *Sec = nullptr;
+  MCSectionCOFF *MCSec = nullptr;
   if (Base && Base->getFragment()) {
-    Sec = SectionMap[Base->getFragment()->getParent()];
-    if (Sym->Section && Sym->Section != Sec)
-      report_fatal_error("conflicting sections for symbol");
+    MCSec = cast<MCSectionCOFF>(Base->getFragment()->getParent());
+    Sec = SectionMap[MCSec];
+  }
+
+  if (MCSec) {
+    if ((Mode == NonDwoOnly && isDwoSection(*MCSec)) ||
+        (Mode == DwoOnly && !isDwoSection(*MCSec)))
+      return;
+    // If this is a section symbol, create an auxiliary symbol (Section
+    // Definition).
+    if (MCSec->getBeginSymbol() == &MCSym) {
+      Sec->Symbol = Sym;
+
+      AuxSymbol &AuxSym = Sym->Aux.emplace_back();
+      AuxSym.AuxType = ATSectionDefinition;
+      AuxSym.Aux.SectionDefinition.Selection = MCSec->getSelection();
+    }
   }
 
   COFFSymbol *Local = nullptr;
@@ -842,12 +847,21 @@ void WinCOFFWriter::executePostLayoutBinding(MCAssembler &Asm,
     defineSection(static_cast<const MCSectionCOFF &>(Section), Layout);
   }
 
-  if (Mode != DwoOnly)
-    for (const MCSymbol &Symbol : Asm.symbols())
-      // Define non-temporary or temporary static (private-linkage) symbols
-      if (!Symbol.isTemporary() ||
-          cast<MCSymbolCOFF>(Symbol).getClass() == COFF::IMAGE_SYM_CLASS_STATIC)
-        DefineSymbol(Symbol, Asm, Layout);
+  auto isSectionSymbol = [](const MCSymbol &Sym) {
+    return Sym.isInSection() && Sym.getSection().getBeginSymbol() == &Sym;
+  };
+
+  for (const MCSymbol &Sym : Asm.symbols())
+    if (isSectionSymbol(Sym))
+      DefineSymbol(Sym, Asm, Layout);
+  if (Mode == DwoOnly)
+    return;
+  for (const MCSymbol &Sym : Asm.symbols())
+    // Define non-temporary or temporary static (private-linkage) symbols
+    if (!isSectionSymbol(Sym) &&
+        (!Sym.isTemporary() ||
+         cast<MCSymbolCOFF>(Sym).getClass() == COFF::IMAGE_SYM_CLASS_STATIC))
+      DefineSymbol(Sym, Asm, Layout);
 }
 
 void WinCOFFWriter::recordRelocation(MCAssembler &Asm,
diff --git a/llvm/test/CodeGen/AArch64/arm64ec-symbols.ll b/llvm/test/CodeGen/AArch64/arm64ec-symbols.ll
index b79dd7d61dd60..b498c9af0baf4 100644
--- a/llvm/test/CodeGen/AArch64/arm64ec-symbols.ll
+++ b/llvm/test/CodeGen/AArch64/arm64ec-symbols.ll
@@ -17,11 +17,11 @@ define void @caller() nounwind {
 ; CHECK-NEXT: .weak_anti_dep  "#func"
 ; CHECK-NEXT: .set "#func", "#func$exit_thunk"{{$}}
 
-; SYM:       [ 8](sec  4)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 #caller
-; SYM:       [21](sec  7)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 #func$exit_thunk
-; SYM:       [33](sec  0)(fl 0x00)(ty   0)(scl  69) (nx 1) 0x00000000 caller
-; SYM-NEXT:  AUX indx 8 srch 4
-; SYM-NEXT:  [35](sec  0)(fl 0x00)(ty   0)(scl  69) (nx 1) 0x00000000 #func
-; SYM-NEXT:  AUX indx 21 srch 4
+; SYM:       [29](sec  4)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 #caller
+; SYM:       [30](sec  0)(fl 0x00)(ty   0)(scl  69) (nx 1) 0x00000000 caller
+; SYM-NEXT:  AUX indx 29 srch 4
+; SYM-NEXT:  [32](sec  0)(fl 0x00)(ty   0)(scl  69) (nx 1) 0x00000000 #func
+; SYM-NEXT:  AUX indx 34 srch 4
+; SYM:       [34](sec  7)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 #func$exit_thunk
 ; SYM:       [39](sec  0)(fl 0x00)(ty   0)(scl  69) (nx 1) 0x00000000 func
-; SYM-NEXT:  AUX indx 35 srch 4
+; SYM-NEXT:  AUX indx 32 srch 4
diff --git a/llvm/test/DebugInfo/X86/InlinedFnLocalVar.ll b/llvm/test/DebugInfo/X86/InlinedFnLocalVar.ll
index 0b27ec8194a1c..1a21725ecaf68 100644
--- a/llvm/test/DebugInfo/X86/InlinedFnLocalVar.ll
+++ b/llvm/test/DebugInfo/X86/InlinedFnLocalVar.ll
@@ -2,7 +2,7 @@
 ; RUN: llc --try-experimental-debuginfo-iterators -mtriple i686-pc-cygwin -O2 %s -o - | FileCheck %s
 ; Check struct X for dead variable xyz from inlined function foo.
 
-; CHECK: Lsection_info
+; CHECK: .section .debug_info,"dr"
 ; CHECK:	DW_TAG_structure_type
 ; CHECK-NEXT:	info_string
 
diff --git a/llvm/test/DebugInfo/X86/ref_addr_relocation.ll b/llvm/test/DebugInfo/X86/ref_addr_relocation.ll
index ba31b2498a384..21e54e73edddb 100644
--- a/llvm/test/DebugInfo/X86/ref_addr_relocation.ll
+++ b/llvm/test/DebugInfo/X86/ref_addr_relocation.ll
@@ -47,7 +47,7 @@
 ; Make sure this is relocatable.
 ; and test that we don't create the labels to emit a correct COFF relocation
 ; ELF-ASM: .quad .debug_info+[[TYPE]] # DW_AT_type
-; COFF-ASM: .secrel32 .Lsection_info+[[TYPE]] # DW_AT_type
+; COFF-ASM: .secrel32 .debug_info+[[TYPE]] # DW_AT_type
 ; DARWIN-ASM2: .quad [[TYPE]] ## DW_AT_type
 ; DARWIN-ASM4: .long [[TYPE]] ## DW_AT_type
 ; CHECK-NOT: DW_TAG_structure_type
diff --git a/llvm/test/MC/AArch64/seh-large-func-multi-epilog.s b/llvm/test/MC/AArch64/seh-large-func-multi-epilog.s
index c2d7f94f7b11f..1f074fa5f1cdf 100644
--- a/llvm/test/MC/AArch64/seh-large-func-multi-epilog.s
+++ b/llvm/test/MC/AArch64/seh-large-func-multi-epilog.s
@@ -43,14 +43,14 @@
 // CHECK-NEXT:]
 // CHECK-LABEL:Relocations [
 // CHECK-NEXT:  Section (1) .text {
-// CHECK-NEXT:    0x94 IMAGE_REL_ARM64_BRANCH26 foo (12)
-// CHECK-NEXT:    0x125068 IMAGE_REL_ARM64_BRANCH26 foo (12)
+// CHECK-NEXT:    0x94 IMAGE_REL_ARM64_BRANCH26 foo (11)
+// CHECK-NEXT:    0x125068 IMAGE_REL_ARM64_BRANCH26 foo (11)
 // CHECK-NEXT:  }
 // CHECK-NEXT:  Section (5) .pdata {
 // CHECK-NEXT:    0x0 IMAGE_REL_ARM64_ADDR32NB .text (0)
-// CHECK-NEXT:    0x4 IMAGE_REL_ARM64_ADDR32NB .xdata (7)
+// CHECK-NEXT:    0x4 IMAGE_REL_ARM64_ADDR32NB .xdata (6)
 // CHECK-NEXT:    0x8 IMAGE_REL_ARM64_ADDR32NB .text (0)
-// CHECK-NEXT:    0xC IMAGE_REL_ARM64_ADDR32NB .xdata (7)
+// CHECK-NEXT:    0xC IMAGE_REL_ARM64_ADDR32NB .xdata (6)
 // CHECK-NEXT:  }
 // CHECK-NEXT:]
 // CHECK-LABEL:UnwindInformation [
diff --git a/llvm/test/MC/AArch64/seh-large-func.s b/llvm/test/MC/AArch64/seh-large-func.s
index d9defe6b18743..60f9b1a20e8f1 100644
--- a/llvm/test/MC/AArch64/seh-large-func.s
+++ b/llvm/test/MC/AArch64/seh-large-func.s
@@ -40,20 +40,20 @@
 // CHECK-NEXT: ]
 // CHECK-LABEL: Relocations [
 // CHECK-NEXT:   Section (1) .text {
-// CHECK-NEXT:     0x186A04 IMAGE_REL_ARM64_BRANCH26 foo (14)
-// CHECK-NEXT:     0x3D091C IMAGE_REL_ARM64_BRANCH26 foo (14)
+// CHECK-NEXT:     0x186A04 IMAGE_REL_ARM64_BRANCH26 foo (11)
+// CHECK-NEXT:     0x3D091C IMAGE_REL_ARM64_BRANCH26 foo (11)
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Section (5) .pdata {
 // CHECK-NEXT:     0x0 IMAGE_REL_ARM64_ADDR32NB .text (0)
-// CHECK-NEXT:     0x4 IMAGE_REL_ARM64_ADDR32NB .x...
[truncated]

Copy link
Contributor

@aengelke aengelke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks ok, but I'm not very familiar with COFF.

if (COMDATSymbol->Section)
report_fatal_error("two sections have the same comdat");
COMDATSymbol->Section = Section;
if (!ComdatSymSet.insert(S->getName()).second)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getOrCreateSymbol should not create symbols with the same name. Couldn't we check this in getCOFFSection? Or store this in the symbol somehow? (I don't like the string map.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I largely keep WinCOFFObjectWriter.cpp unchanged in the update.

report_fatal_error is kept for now, but can be moved to MCContext.cpp as a follow-up by making the symbol redefinable.

DefineSymbol(Sym, Asm, Layout);
if (Mode == DwoOnly)
return;
for (const MCSymbol &Sym : Asm.symbols())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merge the two loops, iterating twice isn't necessary.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Split DWARF places .debug*.dwo sections in a separate file a.dwo. When split DWARF is used, the first loop ensures that the .debug*.dwo symbols are present in a.dwo.

In addition, two loops also allow us to reduce the number of updated tests..

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The update reverts this change.

MCSymbolELF *R;
MCSymbolTableEntry &SymEntry = getSymbolTableEntry(Section);
template <typename Symbol>
Symbol *MCContext::getOrCreateSectionSymbol(StringRef Section) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move up to other getOrCreateSymbolXXX()?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thx. Moved

Created using spr 1.3.5-bogner
Copy link
Contributor

@aengelke aengelke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@MaskRay MaskRay merged commit 04c2785 into main Jun 25, 2024
7 checks passed
@MaskRay MaskRay deleted the users/MaskRay/spr/mccoff-change-how-we-handle-section-symbols branch June 25, 2024 21:00
AlexisPerry pushed a commit to llvm-project-tlp/llvm-project that referenced this pull request Jul 9, 2024
13a79bb (2017) unified `BeginSymbol` and
section symbol for ELF. This patch does the same for COFF.

* In getCOFFSection, all sections now have a `BeginSymbol` (section
  symbol). We do not need a dummy symbol name when `getBeginSymbol` is
  needed (used by AsmParser::Run and DWARF generation).
* Section symbols are in the global symbol table. `call .text` will
  reference the section symbol instead of an undefined symbol. This
  matches GNU assembler. Unlike GNU, redefining the section symbol will
  cause a "symbol 'foo0' is already defined" error (see
  `section-sym-err.s`).

Pull Request: llvm#96459
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants