[llvm] a8058c6 - [DebugInfo] Fix DIE value emitters to be compatible with DWARF64 (2/19).

Igor Kudrin via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 14 22:24:19 PDT 2020


Author: Igor Kudrin
Date: 2020-09-15T11:30:02+07:00
New Revision: a8058c6f8d1d3a360986f05b74f548995b384fcd

URL: https://github.com/llvm/llvm-project/commit/a8058c6f8d1d3a360986f05b74f548995b384fcd
DIFF: https://github.com/llvm/llvm-project/commit/a8058c6f8d1d3a360986f05b74f548995b384fcd.diff

LOG: [DebugInfo] Fix DIE value emitters to be compatible with DWARF64 (2/19).

DW_FORM_sec_offset and DW_FORM_strp imply values of different sizes with
DWARF32 and DWARF64. The patch fixes DIE value classes to use correct
sizes when emitting their values. For DIELocList it ensures that the
requested DWARF form matches the current DWARF format because that class
uses a method that selects the size automatically.

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

Added: 
    llvm/unittests/CodeGen/DIETest.cpp

Modified: 
    llvm/lib/CodeGen/AsmPrinter/DIE.cpp
    llvm/unittests/CodeGen/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/AsmPrinter/DIE.cpp b/llvm/lib/CodeGen/AsmPrinter/DIE.cpp
index f1d255128187..b78a47545458 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DIE.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DIE.cpp
@@ -476,8 +476,7 @@ unsigned DIEExpr::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
   case dwarf::DW_FORM_data8:
     return 8;
   case dwarf::DW_FORM_sec_offset:
-    // FIXME: add support for DWARF64
-    return 4;
+    return AP->getDwarfOffsetByteSize();
   default:
     llvm_unreachable("DIE Value form not supported yet");
   }
@@ -505,8 +504,7 @@ unsigned DIELabel::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
     return 4;
   case dwarf::DW_FORM_sec_offset:
   case dwarf::DW_FORM_strp:
-    // FIXME: add support for DWARF64
-    return 4;
+    return AP->getDwarfOffsetByteSize();
   case dwarf::DW_FORM_addr:
     return AP->MAI->getCodePointerSize();
   default:
@@ -551,8 +549,7 @@ unsigned DIEDelta::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
   case dwarf::DW_FORM_data4:
     return 4;
   case dwarf::DW_FORM_sec_offset:
-    // FIXME: add support for DWARF64
-    return 4;
+    return AP->getDwarfOffsetByteSize();
   default:
     llvm_unreachable("DIE Value form not supported yet");
   }
@@ -822,10 +819,17 @@ unsigned DIELocList::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
   case dwarf::DW_FORM_loclistx:
     return getULEB128Size(Index);
   case dwarf::DW_FORM_data4:
+    assert(!AP->isDwarf64() &&
+           "DW_FORM_data4 is not suitable to emit a pointer to a location list "
+           "in the 64-bit DWARF format");
     return 4;
+  case dwarf::DW_FORM_data8:
+    assert(AP->isDwarf64() &&
+           "DW_FORM_data8 is not suitable to emit a pointer to a location list "
+           "in the 32-bit DWARF format");
+    return 8;
   case dwarf::DW_FORM_sec_offset:
-    // FIXME: add support for DWARF64
-    return 4;
+    return AP->getDwarfOffsetByteSize();
   default:
     llvm_unreachable("DIE Value form not supported yet");
   }

diff  --git a/llvm/unittests/CodeGen/CMakeLists.txt b/llvm/unittests/CodeGen/CMakeLists.txt
index 3af8b7f74297..817ddb1bbf26 100644
--- a/llvm/unittests/CodeGen/CMakeLists.txt
+++ b/llvm/unittests/CodeGen/CMakeLists.txt
@@ -17,6 +17,7 @@ add_llvm_unittest(CodeGenTests
   AArch64SelectionDAGTest.cpp
   AsmPrinterDwarfTest.cpp
   DIEHashTest.cpp
+  DIETest.cpp
   LowLevelTypeTest.cpp
   LexicalScopesTest.cpp
   MachineInstrBundleIteratorTest.cpp

diff  --git a/llvm/unittests/CodeGen/DIETest.cpp b/llvm/unittests/CodeGen/DIETest.cpp
new file mode 100644
index 000000000000..4640d65e6958
--- /dev/null
+++ b/llvm/unittests/CodeGen/DIETest.cpp
@@ -0,0 +1,189 @@
+//===- llvm/unittest/CodeGen/DIETest.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/CodeGen/DIE.h"
+#include "TestAsmPrinter.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/Testing/Support/Error.h"
+
+using namespace llvm;
+using testing::_;
+using testing::SaveArg;
+
+namespace {
+
+using DIETestParams =
+    std::tuple<unsigned, dwarf::DwarfFormat, dwarf::Form, unsigned>;
+
+class DIEFixtureBase : public testing::TestWithParam<DIETestParams> {
+protected:
+  void SetUp() override {
+    unsigned Version;
+    dwarf::DwarfFormat Format;
+    std::tie(Version, Format, Form, Size) = GetParam();
+    auto ExpectedTestPrinter =
+        TestAsmPrinter::create("x86_64-pc-linux", Version, Format);
+    ASSERT_THAT_EXPECTED(ExpectedTestPrinter, Succeeded());
+    TestPrinter = std::move(ExpectedTestPrinter.get());
+  }
+
+  dwarf::Form Form;
+  unsigned Size;
+  std::unique_ptr<TestAsmPrinter> TestPrinter;
+};
+
+struct DIEExprFixture : public DIEFixtureBase {
+  void SetUp() override {
+    DIEFixtureBase::SetUp();
+    if (!TestPrinter)
+      return;
+
+    Val = MCConstantExpr::create(42, TestPrinter->getCtx());
+  }
+
+  const MCExpr *Val = nullptr;
+};
+
+TEST_P(DIEExprFixture, SizeOf) {
+  if (!TestPrinter)
+    return;
+
+  DIEExpr Tst(Val);
+  EXPECT_EQ(Size, Tst.SizeOf(TestPrinter->getAP(), Form));
+}
+
+TEST_P(DIEExprFixture, EmitValue) {
+  if (!TestPrinter)
+    return;
+
+  DIEExpr Tst(Val);
+  EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(Val, Size, _));
+  Tst.emitValue(TestPrinter->getAP(), Form);
+}
+
+INSTANTIATE_TEST_CASE_P(
+    DIETestParams, DIEExprFixture,
+    testing::Values(
+        DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_data4, 4u},
+        DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_data8, 8u},
+        DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_sec_offset, 4u},
+        DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_data4, 4u},
+        DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_data8, 8u},
+        DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_sec_offset, 8u}), );
+
+struct DIELabelFixture : public DIEFixtureBase {
+  void SetUp() override {
+    DIEFixtureBase::SetUp();
+    if (!TestPrinter)
+      return;
+
+    Val = TestPrinter->getCtx().createTempSymbol();
+  }
+
+  const MCSymbol *Val = nullptr;
+};
+
+TEST_P(DIELabelFixture, SizeOf) {
+  if (!TestPrinter)
+    return;
+
+  DIELabel Tst(Val);
+  EXPECT_EQ(Size, Tst.SizeOf(TestPrinter->getAP(), Form));
+}
+
+TEST_P(DIELabelFixture, EmitValue) {
+  if (!TestPrinter)
+    return;
+
+  DIELabel Tst(Val);
+
+  const MCExpr *Arg0 = nullptr;
+  EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, Size, _))
+      .WillOnce(SaveArg<0>(&Arg0));
+  Tst.emitValue(TestPrinter->getAP(), Form);
+
+  const MCSymbolRefExpr *ActualArg0 = dyn_cast_or_null<MCSymbolRefExpr>(Arg0);
+  ASSERT_NE(ActualArg0, nullptr);
+  EXPECT_EQ(&(ActualArg0->getSymbol()), Val);
+}
+
+INSTANTIATE_TEST_CASE_P(
+    DIETestParams, DIELabelFixture,
+    testing::Values(
+        DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_data4, 4u},
+        DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_sec_offset, 4u},
+        DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_strp, 4u},
+        DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_addr, 8u},
+        DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_data4, 4u},
+        DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_sec_offset, 8u},
+        DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_strp, 8u},
+        DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_addr, 8u}), );
+
+struct DIEDeltaFixture : public DIEFixtureBase {
+  void SetUp() override {
+    DIEFixtureBase::SetUp();
+    if (!TestPrinter)
+      return;
+
+    Hi = TestPrinter->getCtx().createTempSymbol();
+    Lo = TestPrinter->getCtx().createTempSymbol();
+  }
+
+  const MCSymbol *Hi = nullptr;
+  const MCSymbol *Lo = nullptr;
+};
+
+TEST_P(DIEDeltaFixture, SizeOf) {
+  if (!TestPrinter)
+    return;
+
+  DIEDelta Tst(Hi, Lo);
+  EXPECT_EQ(Size, Tst.SizeOf(TestPrinter->getAP(), Form));
+}
+
+TEST_P(DIEDeltaFixture, EmitValue) {
+  if (!TestPrinter)
+    return;
+
+  DIEDelta Tst(Hi, Lo);
+  EXPECT_CALL(TestPrinter->getMS(), emitAbsoluteSymbolDiff(Hi, Lo, Size));
+  Tst.emitValue(TestPrinter->getAP(), Form);
+}
+
+INSTANTIATE_TEST_CASE_P(
+    DIETestParams, DIEDeltaFixture,
+    testing::Values(
+        DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_data4, 4u},
+        DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_sec_offset, 4u},
+        DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_data4, 4u},
+        DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_sec_offset, 8u}), );
+
+struct DIELocListFixture : public DIEFixtureBase {
+  void SetUp() override { DIEFixtureBase::SetUp(); }
+};
+
+TEST_P(DIELocListFixture, SizeOf) {
+  if (!TestPrinter)
+    return;
+
+  DIELocList Tst(999);
+  EXPECT_EQ(Size, Tst.SizeOf(TestPrinter->getAP(), Form));
+}
+
+INSTANTIATE_TEST_CASE_P(
+    DIETestParams, DIELocListFixture,
+    testing::Values(
+        DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_loclistx, 2u},
+        DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_data4, 4u},
+        DIETestParams{4, dwarf::DWARF32, dwarf::DW_FORM_sec_offset, 4u},
+        DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_loclistx, 2u},
+        DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_data8, 8u},
+        DIETestParams{4, dwarf::DWARF64, dwarf::DW_FORM_sec_offset, 8u}), );
+
+} // end namespace


        


More information about the llvm-commits mailing list