diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2666,10 +2666,12 @@ HelpText<"Generate source-level debug information with dwarf version 4">; def gdwarf_5 : Flag<["-"], "gdwarf-5">, Group, HelpText<"Generate source-level debug information with dwarf version 5">; -def gdwarf64 : Flag<["-"], "gdwarf64">, Group, Flags<[CC1Option]>, +def gdwarf64 : Flag<["-"], "gdwarf64">, Group, + Flags<[CC1Option, CC1AsOption]>, HelpText<"Enables DWARF64 format for ELF binaries, if debug information emission is enabled.">, MarshallingInfoFlag>; -def gdwarf32 : Flag<["-"], "gdwarf32">, Group, Flags<[CC1Option]>, +def gdwarf32 : Flag<["-"], "gdwarf32">, Group, + Flags<[CC1Option, CC1AsOption]>, HelpText<"Enables DWARF32 format for ELF binaries, if debug information emission is enabled.">; def gcodeview : Flag<["-"], "gcodeview">, diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -3749,6 +3749,29 @@ return DwarfFissionKind::None; } +static void renderDwarfFormat(const Driver &D, const llvm::Triple &T, + const ArgList &Args, ArgStringList &CmdArgs, + unsigned DwarfVersion) { + auto *DwarfFormatArg = + Args.getLastArg(options::OPT_gdwarf64, options::OPT_gdwarf32); + if (!DwarfFormatArg) + return; + + if (DwarfFormatArg->getOption().matches(options::OPT_gdwarf64)) { + if (DwarfVersion < 3) + D.Diag(diag::err_drv_argument_only_allowed_with) + << DwarfFormatArg->getAsString(Args) << "DWARFv3 or greater"; + else if (!T.isArch64Bit()) + D.Diag(diag::err_drv_argument_only_allowed_with) + << DwarfFormatArg->getAsString(Args) << "64 bit architecture"; + else if (!T.isOSBinFormatELF()) + D.Diag(diag::err_drv_argument_only_allowed_with) + << DwarfFormatArg->getAsString(Args) << "ELF platforms"; + } + + DwarfFormatArg->render(Args, CmdArgs); +} + static void renderDebugOptions(const ToolChain &TC, const Driver &D, const llvm::Triple &T, const ArgList &Args, bool EmitCodeView, bool IRInput, @@ -4049,25 +4072,7 @@ if (DebuggerTuning == llvm::DebuggerKind::SCE) CmdArgs.push_back("-dwarf-explicit-import"); - auto *DwarfFormatArg = - Args.getLastArg(options::OPT_gdwarf64, options::OPT_gdwarf32); - if (DwarfFormatArg && - DwarfFormatArg->getOption().matches(options::OPT_gdwarf64)) { - const llvm::Triple &RawTriple = TC.getTriple(); - if (EffectiveDWARFVersion < 3) - D.Diag(diag::err_drv_argument_only_allowed_with) - << DwarfFormatArg->getAsString(Args) << "DWARFv3 or greater"; - else if (!RawTriple.isArch64Bit()) - D.Diag(diag::err_drv_argument_only_allowed_with) - << DwarfFormatArg->getAsString(Args) << "64 bit architecture"; - else if (!RawTriple.isOSBinFormatELF()) - D.Diag(diag::err_drv_argument_only_allowed_with) - << DwarfFormatArg->getAsString(Args) << "ELF platforms"; - } - - if (DwarfFormatArg) - DwarfFormatArg->render(Args, CmdArgs); - + renderDwarfFormat(D, T, Args, CmdArgs, EffectiveDWARFVersion); RenderDebugInfoCompressionArgs(Args, CmdArgs, D, TC); } @@ -7211,6 +7216,7 @@ } RenderDebugEnablingArgs(Args, CmdArgs, DebugInfoKind, DwarfVersion, llvm::DebuggerKind::Default); + renderDwarfFormat(D, Triple, Args, CmdArgs, DwarfVersion); RenderDebugInfoCompressionArgs(Args, CmdArgs, D, getToolChain()); diff --git a/clang/test/Driver/debug-options-as.c b/clang/test/Driver/debug-options-as.c --- a/clang/test/Driver/debug-options-as.c +++ b/clang/test/Driver/debug-options-as.c @@ -32,3 +32,31 @@ // // P: "-cc1as" // P: "-dwarf-debug-producer" + +// Check that -gdwarf64 is passed to cc1as. +// RUN: %clang -### -c -gdwarf64 -gdwarf-5 -target x86_64 -integrated-as -x assembler %s 2>&1 \ +// RUN: | FileCheck -check-prefix=GDWARF64_ON %s +// RUN: %clang -### -c -gdwarf64 -gdwarf-4 -target x86_64 -integrated-as -x assembler %s 2>&1 \ +// RUN: | FileCheck -check-prefix=GDWARF64_ON %s +// RUN: %clang -### -c -gdwarf64 -gdwarf-3 -target x86_64 -integrated-as -x assembler %s 2>&1 \ +// RUN: | FileCheck -check-prefix=GDWARF64_ON %s +// GDWARF64_ON: "-cc1as" +// GDWARF64_ON: "-gdwarf64" + +// Check that -gdwarf64 can be reverted with -gdwarf32. +// RUN: %clang -### -c -gdwarf64 -gdwarf32 -gdwarf-4 -target x86_64 -integrated-as -x assembler %s 2>&1 \ +// RUN: | FileCheck -check-prefix=GDWARF64_OFF %s +// GDWARF64_OFF: "-cc1as" +// GDWARF64_OFF-NOT: "-gdwarf64" + +// Check that an error is reported if -gdwarf64 cannot be used. +// RUN: %clang -### -c -gdwarf64 -gdwarf-2 -target x86_64 -integrated-as -x assembler %s 2>&1 \ +// RUN: | FileCheck -check-prefix=GDWARF64_VER %s +// RUN: %clang -### -c -gdwarf64 -gdwarf-4 -target i386-linux-gnu %s 2>&1 \ +// RUN: | FileCheck -check-prefix=GDWARF64_32ARCH %s +// RUN: %clang -### -c -gdwarf64 -gdwarf-4 -target x86_64-apple-darwin %s 2>&1 \ +// RUN: | FileCheck -check-prefix=GDWARF64_ELF %s +// +// GDWARF64_VER: error: invalid argument '-gdwarf64' only allowed with 'DWARFv3 or greater' +// GDWARF64_32ARCH: error: invalid argument '-gdwarf64' only allowed with '64 bit architecture' +// GDWARF64_ELF: error: invalid argument '-gdwarf64' only allowed with 'ELF platforms' diff --git a/clang/test/Misc/cc1as-debug-format.s b/clang/test/Misc/cc1as-debug-format.s new file mode 100644 --- /dev/null +++ b/clang/test/Misc/cc1as-debug-format.s @@ -0,0 +1,24 @@ +// REQUIRES: x86-registered-target +/// DWARF32 debug info is produced by default, when neither -gdwarf32 nor -gdwarf64 is given. +// RUN: %clang -cc1as -triple x86_64-pc-linux-gnu -filetype obj -debug-info-kind=limited -dwarf-version=4 %s -o %t +// RUN: llvm-dwarfdump -all %t | FileCheck %s --check-prefixes=CHECK,DWARF32 +/// -gdwarf64 causes generating DWARF64 debug info. +// RUN: %clang -cc1as -triple x86_64-pc-linux-gnu -filetype obj -gdwarf64 -debug-info-kind=limited -dwarf-version=4 %s -o %t +// RUN: llvm-dwarfdump -all %t | FileCheck %s --check-prefixes=CHECK,DWARF64 +/// -gdwarf32 is also handled and produces DWARF32 debug info. +// RUN: %clang -cc1as -triple x86_64-pc-linux-gnu -filetype obj -gdwarf32 -debug-info-kind=limited -dwarf-version=4 %s -o %t +// RUN: llvm-dwarfdump -all %t | FileCheck %s --check-prefixes=CHECK,DWARF32 + +// CHECK: .debug_info contents: +// DWARF32-NEXT: format = DWARF32 +// DWARF64-NEXT: format = DWARF64 + +// CHECK: .debug_line contents: +// CHECK-NEXT: debug_line[ +// CHECK-NEXT: Line table prologue: +// CHECK-NEXT: total_length: +// DWARF32-NEXT: format: DWARF32 +// DWARF64-NEXT: format: DWARF64 + +.text + nop diff --git a/clang/tools/driver/cc1as_main.cpp b/clang/tools/driver/cc1as_main.cpp --- a/clang/tools/driver/cc1as_main.cpp +++ b/clang/tools/driver/cc1as_main.cpp @@ -91,6 +91,7 @@ unsigned SaveTemporaryLabels : 1; unsigned GenDwarfForAssembly : 1; unsigned RelaxELFRelocations : 1; + unsigned Dwarf64 : 1; unsigned DwarfVersion; std::string DwarfDebugFlags; std::string DwarfDebugProducer; @@ -160,6 +161,7 @@ FatalWarnings = 0; NoWarn = 0; IncrementalLinkerCompatible = 0; + Dwarf64 = 0; DwarfVersion = 0; EmbedBitcode = 0; } @@ -231,6 +233,8 @@ } Opts.RelaxELFRelocations = Args.hasArg(OPT_mrelax_relocations); + if (auto *DwarfFormatArg = Args.getLastArg(OPT_gdwarf64, OPT_gdwarf32)) + Opts.Dwarf64 = DwarfFormatArg->getOption().matches(OPT_gdwarf64); Opts.DwarfVersion = getLastArgIntValue(Args, OPT_dwarf_version_EQ, 2, Diags); Opts.DwarfDebugFlags = std::string(Args.getLastArgValue(OPT_dwarf_debug_flags)); @@ -417,6 +421,7 @@ Ctx.addDebugPrefixMapEntry(KV.first, KV.second); if (!Opts.MainFileName.empty()) Ctx.setMainFileName(StringRef(Opts.MainFileName)); + Ctx.setDwarfFormat(Opts.Dwarf64 ? dwarf::DWARF64 : dwarf::DWARF32); Ctx.setDwarfVersion(Opts.DwarfVersion); if (Opts.GenDwarfForAssembly) Ctx.setGenDwarfRootFile(Opts.InputFile,