MaskRay created this revision.
MaskRay added reviewers: compnerd, jrtc27, kito.cheng.
Herald added subscribers: sunshaoce, VincentWu, luke957, StephenFan, vkmr, 
frasercrmck, luismarques, apazos, sameer.abuasal, s.egerton, Jim, jocewei, 
PkmX, the_o, brucehoult, MartinMosbeck, rogfer01, edward-jones, zzheng, 
shiva0217, kito-cheng, niosHD, sabuasal, simoncook, johnrusso, rbar, asb, 
arichardson.
Herald added a project: All.
MaskRay requested review of this revision.
Herald added subscribers: cfe-commits, pcwang-thead.
Herald added a project: clang.

-gsplit-dwarf produces a .dwo file which will not be processed by the linker. If
.dwo files contain relocations, they will not be resolved. Therefore the
practice is that .dwo files do not contain relocations. Since features like
address ranges need relocations and cannot be resolved without linking, split
DWARF is foundamentally incompatible with linker relaxation.

Currently there is a difficult-to-read MC error with -gsplit-dwarf with RISC-V 
-mrelax

  % clang --target=riscv64-linux-gnu -g -gsplit-dwarf -c a.c
  error: A dwo section may not contain relocations

Report a driver error instead.

Close https://github.com/llvm/llvm-project/issues/56642


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D130190

Files:
  clang/include/clang/Basic/DiagnosticDriverKinds.td
  clang/lib/Driver/ToolChains/Arch/RISCV.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Driver/ToolChains/Clang.h
  clang/test/Driver/riscv-features.c


Index: clang/test/Driver/riscv-features.c
===================================================================
--- clang/test/Driver/riscv-features.c
+++ clang/test/Driver/riscv-features.c
@@ -35,3 +35,10 @@
 // RUN: not %clang -cc1 -triple riscv64-unknown-elf -target-feature +e 2>&1 | 
FileCheck %s -check-prefix=RV64-WITH-E
 
 // RV64-WITH-E: error: invalid feature combination: standard user-level 
extension 'e' requires 'rv32'
+
+// RUN: not %clang -c --target=riscv64-linux-gnu -gsplit-dwarf %s 2>&1 | 
FileCheck %s --check-prefix=ERR-SPLIT-DWARF
+// RUN: not %clang -c --target=riscv64 -gsplit-dwarf=single %s 2>&1 | 
FileCheck %s --check-prefix=ERR-SPLIT-DWARF
+// RUN: %clang -### -c --target=riscv64 -mno-relax -g -gsplit-dwarf %s 2>&1 | 
FileCheck %s --check-prefix=SPLIT-DWARF
+
+// ERR-SPLIT-DWARF: error: -gsplit-dwarf{{.*}} is incompatible with RISC-V 
linker relaxation (-mrelax)
+// SPLIT-DWARF:     "-split-dwarf-file"
Index: clang/lib/Driver/ToolChains/Clang.h
===================================================================
--- clang/lib/Driver/ToolChains/Clang.h
+++ clang/lib/Driver/ToolChains/Clang.h
@@ -198,6 +198,12 @@
                     const char *LinkingOutput) const override;
 };
 
+enum class DwarfFissionKind { None, Split, Single };
+
+DwarfFissionKind getDebugFissionKind(const Driver &D,
+                                     const llvm::opt::ArgList &Args,
+                                     llvm::opt::Arg *&Arg);
+
 } // end namespace tools
 
 } // end namespace driver
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -4051,9 +4051,7 @@
                      options::OPT_fno_spell_checking);
 }
 
-enum class DwarfFissionKind { None, Split, Single };
-
-static DwarfFissionKind getDebugFissionKind(const Driver &D,
+DwarfFissionKind tools::getDebugFissionKind(const Driver &D,
                                             const ArgList &Args, Arg *&Arg) {
   Arg = Args.getLastArg(options::OPT_gsplit_dwarf, 
options::OPT_gsplit_dwarf_EQ,
                         options::OPT_gno_split_dwarf);
Index: clang/lib/Driver/ToolChains/Arch/RISCV.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -7,6 +7,7 @@
 
//===----------------------------------------------------------------------===//
 
 #include "RISCV.h"
+#include "../Clang.h"
 #include "ToolChains/CommonArgs.h"
 #include "clang/Basic/CharInfo.h"
 #include "clang/Driver/Driver.h"
@@ -137,10 +138,15 @@
     Features.push_back("+reserve-x31");
 
   // -mrelax is default, unless -mno-relax is specified.
-  if (Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax, true))
+  if (Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax, true)) {
     Features.push_back("+relax");
-  else
+    Arg *A;
+    if (getDebugFissionKind(D, Args, A) != DwarfFissionKind::None)
+      D.Diag(clang::diag::err_drv_riscv_incompatible_with_linker_relaxation)
+          << A->getAsString(Args);
+  } else {
     Features.push_back("-relax");
+  }
 
   // GCC Compatibility: -mno-save-restore is default, unless -msave-restore is
   // specified.
Index: clang/include/clang/Basic/DiagnosticDriverKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -678,4 +678,7 @@
 def err_drv_invalid_empty_dxil_validator_version : Error<
   "invalid validator version : %0\n"
   "If validator major version is 0, minor version must also be 0.">;
+
+def err_drv_riscv_incompatible_with_linker_relaxation : Error<
+  "%0 is incompatible with RISC-V linker relaxation (-mrelax)">;
 }


Index: clang/test/Driver/riscv-features.c
===================================================================
--- clang/test/Driver/riscv-features.c
+++ clang/test/Driver/riscv-features.c
@@ -35,3 +35,10 @@
 // RUN: not %clang -cc1 -triple riscv64-unknown-elf -target-feature +e 2>&1 | FileCheck %s -check-prefix=RV64-WITH-E
 
 // RV64-WITH-E: error: invalid feature combination: standard user-level extension 'e' requires 'rv32'
+
+// RUN: not %clang -c --target=riscv64-linux-gnu -gsplit-dwarf %s 2>&1 | FileCheck %s --check-prefix=ERR-SPLIT-DWARF
+// RUN: not %clang -c --target=riscv64 -gsplit-dwarf=single %s 2>&1 | FileCheck %s --check-prefix=ERR-SPLIT-DWARF
+// RUN: %clang -### -c --target=riscv64 -mno-relax -g -gsplit-dwarf %s 2>&1 | FileCheck %s --check-prefix=SPLIT-DWARF
+
+// ERR-SPLIT-DWARF: error: -gsplit-dwarf{{.*}} is incompatible with RISC-V linker relaxation (-mrelax)
+// SPLIT-DWARF:     "-split-dwarf-file"
Index: clang/lib/Driver/ToolChains/Clang.h
===================================================================
--- clang/lib/Driver/ToolChains/Clang.h
+++ clang/lib/Driver/ToolChains/Clang.h
@@ -198,6 +198,12 @@
                     const char *LinkingOutput) const override;
 };
 
+enum class DwarfFissionKind { None, Split, Single };
+
+DwarfFissionKind getDebugFissionKind(const Driver &D,
+                                     const llvm::opt::ArgList &Args,
+                                     llvm::opt::Arg *&Arg);
+
 } // end namespace tools
 
 } // end namespace driver
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -4051,9 +4051,7 @@
                      options::OPT_fno_spell_checking);
 }
 
-enum class DwarfFissionKind { None, Split, Single };
-
-static DwarfFissionKind getDebugFissionKind(const Driver &D,
+DwarfFissionKind tools::getDebugFissionKind(const Driver &D,
                                             const ArgList &Args, Arg *&Arg) {
   Arg = Args.getLastArg(options::OPT_gsplit_dwarf, options::OPT_gsplit_dwarf_EQ,
                         options::OPT_gno_split_dwarf);
Index: clang/lib/Driver/ToolChains/Arch/RISCV.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "RISCV.h"
+#include "../Clang.h"
 #include "ToolChains/CommonArgs.h"
 #include "clang/Basic/CharInfo.h"
 #include "clang/Driver/Driver.h"
@@ -137,10 +138,15 @@
     Features.push_back("+reserve-x31");
 
   // -mrelax is default, unless -mno-relax is specified.
-  if (Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax, true))
+  if (Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax, true)) {
     Features.push_back("+relax");
-  else
+    Arg *A;
+    if (getDebugFissionKind(D, Args, A) != DwarfFissionKind::None)
+      D.Diag(clang::diag::err_drv_riscv_incompatible_with_linker_relaxation)
+          << A->getAsString(Args);
+  } else {
     Features.push_back("-relax");
+  }
 
   // GCC Compatibility: -mno-save-restore is default, unless -msave-restore is
   // specified.
Index: clang/include/clang/Basic/DiagnosticDriverKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -678,4 +678,7 @@
 def err_drv_invalid_empty_dxil_validator_version : Error<
   "invalid validator version : %0\n"
   "If validator major version is 0, minor version must also be 0.">;
+
+def err_drv_riscv_incompatible_with_linker_relaxation : Error<
+  "%0 is incompatible with RISC-V linker relaxation (-mrelax)">;
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to