[llvm] [MC][ELF] Fix printing group signature symbols. (PR #112543)

Ivan Kosarev via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 17 09:39:54 PDT 2024


https://github.com/kosarev updated https://github.com/llvm/llvm-project/pull/112543

>From 7354caa9e36efe86752513c31c0ca4ad88cabdfa Mon Sep 17 00:00:00 2001
From: Ivan Kosarev <ivan.kosarev at amd.com>
Date: Wed, 16 Oct 2024 14:27:18 +0100
Subject: [PATCH] [MC][ELF] Fix printing group signature symbols.

They may be not known.

Change-Id: Ie69060a2f7d049a11afa7b5e7c7f132ccb0a592d
---
 llvm/lib/MC/MCSectionELF.cpp     |  6 +-
 llvm/unittests/MC/CMakeLists.txt |  1 +
 llvm/unittests/MC/MCStreamer.cpp | 96 ++++++++++++++++++++++++++++++++
 3 files changed, 101 insertions(+), 2 deletions(-)
 create mode 100644 llvm/unittests/MC/MCStreamer.cpp

diff --git a/llvm/lib/MC/MCSectionELF.cpp b/llvm/lib/MC/MCSectionELF.cpp
index 25e62b70b5e2a0..3dc9a67e63939a 100644
--- a/llvm/lib/MC/MCSectionELF.cpp
+++ b/llvm/lib/MC/MCSectionELF.cpp
@@ -191,8 +191,10 @@ void MCSectionELF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
   }
 
   if (Flags & ELF::SHF_GROUP) {
-    OS << ",";
-    printName(OS, Group.getPointer()->getName());
+    if (const MCSymbolELF *Signature = Group.getPointer()) {
+      OS << ",";
+      printName(OS, Signature->getName());
+    }
     if (isComdat())
       OS << ",comdat";
   }
diff --git a/llvm/unittests/MC/CMakeLists.txt b/llvm/unittests/MC/CMakeLists.txt
index da8e219113f465..12f2bebda1c7e4 100644
--- a/llvm/unittests/MC/CMakeLists.txt
+++ b/llvm/unittests/MC/CMakeLists.txt
@@ -18,6 +18,7 @@ add_llvm_unittest(MCTests
   DwarfLineTables.cpp
   DwarfLineTableHeaders.cpp
   MCInstPrinter.cpp
+  MCStreamer.cpp
   StringTableBuilderTest.cpp
   TargetRegistry.cpp
   MCDisassemblerTest.cpp
diff --git a/llvm/unittests/MC/MCStreamer.cpp b/llvm/unittests/MC/MCStreamer.cpp
new file mode 100644
index 00000000000000..f1f6793c80a66a
--- /dev/null
+++ b/llvm/unittests/MC/MCStreamer.cpp
@@ -0,0 +1,96 @@
+//===- llvm/unittest/MC/MCStreamer.cpp ------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSectionELF.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+class MCStreamerTest : public ::testing::Test {
+public:
+  static constexpr char TripleName[] = "x86_64-pc-linux";
+  std::unique_ptr<MCRegisterInfo> MRI;
+  std::unique_ptr<MCAsmInfo> MAI;
+  std::unique_ptr<const MCSubtargetInfo> STI;
+  const Target *TheTarget;
+
+  struct StreamerContext {
+    std::unique_ptr<MCContext> Ctx;
+    std::unique_ptr<const MCInstrInfo> MII;
+    std::unique_ptr<MCInstPrinter> Printer;
+    std::unique_ptr<MCStreamer> Streamer;
+  };
+
+  MCStreamerTest() {
+    llvm::InitializeAllTargetInfos();
+    llvm::InitializeAllTargetMCs();
+    llvm::InitializeAllDisassemblers();
+
+    // If we didn't build the target, do not run the test.
+    std::string Error;
+    TheTarget = TargetRegistry::lookupTarget(TripleName, Error);
+    if (!TheTarget)
+      return;
+
+    MRI.reset(TheTarget->createMCRegInfo(TripleName));
+    MCTargetOptions MCOptions;
+    MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
+    STI.reset(TheTarget->createMCSubtargetInfo(TripleName, "", ""));
+  }
+
+  /// Create all data structures necessary to operate an assembler.
+  StreamerContext createStreamer(raw_pwrite_stream &OS) {
+    StreamerContext Res;
+    Res.Ctx =
+        std::make_unique<MCContext>(Triple(TripleName), MAI.get(), MRI.get(),
+                                    /*MSTI=*/nullptr);
+    Res.MII.reset(TheTarget->createMCInstrInfo());
+
+    Res.Printer.reset(TheTarget->createMCInstPrinter(
+        Triple(TripleName), MAI->getAssemblerDialect(), *MAI, *Res.MII, *MRI));
+
+    MCCodeEmitter *MCE = TheTarget->createMCCodeEmitter(*Res.MII, *Res.Ctx);
+    MCAsmBackend *MAB =
+        TheTarget->createMCAsmBackend(*STI, *MRI, MCTargetOptions());
+    std::unique_ptr<formatted_raw_ostream> Out(new formatted_raw_ostream(OS));
+    Res.Streamer.reset(TheTarget->createAsmStreamer(
+        *Res.Ctx, std::move(Out), Res.Printer.get(),
+        std::unique_ptr<MCCodeEmitter>(MCE),
+        std::unique_ptr<MCAsmBackend>(MAB)));
+    return Res;
+  }
+};
+} // namespace
+
+TEST_F(MCStreamerTest, AnonymousGroup) {
+  if (!MRI)
+    GTEST_SKIP();
+
+  SmallString<0> Out;
+  raw_svector_ostream S(Out);
+  StreamerContext C = createStreamer(S);
+
+  // Test that switching to a group section with no associated signature name
+  // doesn't crash.
+  C.Streamer->switchSection(
+      C.Ctx->getELFSection("foo", ELF::SHT_PROGBITS, ELF::SHF_GROUP));
+  C.Streamer->finish();
+}



More information about the llvm-commits mailing list