diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -114,6 +114,10 @@ CODEGENOPT(ForceDwarfFrameSection , 1, 0) ///< Set when -fforce-dwarf-frame is ///< enabled. +///< Set when -femit-dwarf-unwind is passed. +ENUM_CODEGENOPT(EmitDwarfUnwind, llvm::EmitDwarfUnwindType, 2, + llvm::EmitDwarfUnwindType::Default) + ///< Set when -fxray-always-emit-customevents is enabled. CODEGENOPT(XRayAlwaysEmitCustomEvents , 1, 0) 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 @@ -3044,6 +3044,13 @@ defm force_dwarf_frame : BoolFOption<"force-dwarf-frame", CodeGenOpts<"ForceDwarfFrameSection">, DefaultFalse, PosFlag, NegFlag>; +def femit_dwarf_unwind_EQ : Joined<["-"], "femit-dwarf-unwind=">, + Group, Flags<[CC1Option, CC1AsOption]>, + HelpText<"When to emit DWARF unwind (EH frame) info">, + Values<"always,no-compact-unwind,default">, + NormalizedValues<["Always", "NoCompactUnwind", "Default"]>, + NormalizedValuesScope<"llvm::EmitDwarfUnwindType">, + MarshallingInfoEnum, "Default">; def g_Flag : Flag<["-"], "g">, Group, HelpText<"Generate source-level debug information">; def gline_tables_only : Flag<["-"], "gline-tables-only">, Group, diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -453,6 +453,7 @@ } Options.MCOptions.SplitDwarfFile = CodeGenOpts.SplitDwarfFile; + Options.MCOptions.EmitDwarfUnwind = CodeGenOpts.getEmitDwarfUnwind(); Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll; Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels; Options.MCOptions.MCUseDwarfDirectory = 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 @@ -2518,6 +2518,8 @@ DefaultIncrementalLinkerCompatible)) CmdArgs.push_back("-mincremental-linker-compatible"); + Args.AddLastArg(CmdArgs, options::OPT_femit_dwarf_unwind_EQ); + // If you add more args here, also add them to the block below that // starts with "// If CollectArgsForIntegratedAssembler() isn't called below". @@ -4622,6 +4624,7 @@ } Args.ClaimAllArgs(options::OPT_Wa_COMMA); Args.ClaimAllArgs(options::OPT_Xassembler); + Args.ClaimAllArgs(options::OPT_femit_dwarf_unwind_EQ); } if (isa(JA)) { diff --git a/clang/test/Driver/femit-dwarf-unwind.c b/clang/test/Driver/femit-dwarf-unwind.c new file mode 100644 --- /dev/null +++ b/clang/test/Driver/femit-dwarf-unwind.c @@ -0,0 +1,12 @@ +// RUN: rm -rf %t; mkdir %t +// RUN: %clang -target x86_64-apple-macos11.0 -c %s -o %t/x86_64.o +// RUN: %clang -target x86_64-apple-macos11.0 -femit-dwarf-unwind=no-compact-unwind -c %s -o %t/x86_64-no-dwarf.o +// RUN: llvm-objdump --macho --dwarf=frames %t/x86_64.o | FileCheck %s --check-prefix=WITH-FDE +// RUN: llvm-objdump --macho --dwarf=frames %t/x86_64-no-dwarf.o | FileCheck %s --check-prefix=NO-FDE + +// WITH-FDE: FDE +// NO-FDE-NOT: FDE + +int foo() { + return 1; +} diff --git a/clang/test/Driver/femit-dwarf-unwind.s b/clang/test/Driver/femit-dwarf-unwind.s new file mode 100644 --- /dev/null +++ b/clang/test/Driver/femit-dwarf-unwind.s @@ -0,0 +1,15 @@ +// RUN: rm -rf %t; mkdir %t +// RUN: %clang -target x86_64-apple-macos11.0 -c %s -o %t/x86_64.o +// RUN: %clang -target x86_64-apple-macos11.0 -femit-dwarf-unwind=no-compact-unwind -c %s -o %t/x86_64-no-dwarf.o +// RUN: llvm-objdump --macho --dwarf=frames %t/x86_64.o | FileCheck %s --check-prefix=WITH-FDE +// RUN: llvm-objdump --macho --dwarf=frames %t/x86_64-no-dwarf.o | FileCheck %s --check-prefix=NO-FDE + +// WITH-FDE: FDE +// NO-FDE-NOT: FDE + +.text +_foo: + .cfi_startproc + .cfi_def_cfa_offset 8 + ret + .cfi_endproc 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 @@ -137,6 +137,9 @@ unsigned IncrementalLinkerCompatible : 1; unsigned EmbedBitcode : 1; + /// Whether to emit DWARF unwind info. + EmitDwarfUnwindType EmitDwarfUnwind; + /// The name of the relocation model to use. std::string RelocationModel; @@ -317,6 +320,14 @@ .Default(0); } + if (auto *A = Args.getLastArg(OPT_femit_dwarf_unwind_EQ)) { + Opts.EmitDwarfUnwind = + llvm::StringSwitch(A->getValue()) + .Case("always", EmitDwarfUnwindType::Always) + .Case("no-compact-unwind", EmitDwarfUnwindType::NoCompactUnwind) + .Case("default", EmitDwarfUnwindType::Default); + } + return Success; } @@ -367,6 +378,8 @@ assert(MRI && "Unable to create target register info!"); MCTargetOptions MCOptions; + MCOptions.EmitDwarfUnwind = Opts.EmitDwarfUnwind; + std::unique_ptr MAI( TheTarget->createMCAsmInfo(*MRI, Opts.Triple, MCOptions)); assert(MAI && "Unable to create target asm info!"); diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h --- a/llvm/include/llvm/MC/MCContext.h +++ b/llvm/include/llvm/MC/MCContext.h @@ -67,6 +67,7 @@ class SMDiagnostic; class SMLoc; class SourceMgr; +enum class EmitDwarfUnwindType; /// Context object for machine code objects. This class owns all of the /// sections that it creates. @@ -772,6 +773,7 @@ bool getGenDwarfForAssembly() { return GenDwarfForAssembly; } void setGenDwarfForAssembly(bool Value) { GenDwarfForAssembly = Value; } unsigned getGenDwarfFileNumber() { return GenDwarfFileNumber; } + EmitDwarfUnwindType emitDwarfUnwindInfo() const; void setGenDwarfFileNumber(unsigned FileNumber) { GenDwarfFileNumber = FileNumber; diff --git a/llvm/include/llvm/MC/MCTargetOptions.h b/llvm/include/llvm/MC/MCTargetOptions.h --- a/llvm/include/llvm/MC/MCTargetOptions.h +++ b/llvm/include/llvm/MC/MCTargetOptions.h @@ -31,6 +31,12 @@ Z, ///< zlib style complession }; +enum class EmitDwarfUnwindType { + Always, // Always emit dwarf unwind + NoCompactUnwind, // Only emit if compact unwind isn't available + Default, // Default behavior is based on the target +}; + class StringRef; class MCTargetOptions { @@ -56,6 +62,9 @@ bool PreserveAsmComments : 1; bool Dwarf64 : 1; + + EmitDwarfUnwindType EmitDwarfUnwind; + int DwarfVersion = 0; enum DwarfDirectory { diff --git a/llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h b/llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h --- a/llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h +++ b/llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h @@ -20,6 +20,7 @@ namespace llvm { class MCTargetOptions; +enum class EmitDwarfUnwindType; namespace mc { @@ -32,6 +33,8 @@ bool getDwarf64(); +EmitDwarfUnwindType getEmitDwarfUnwind(); + bool getShowMCInst(); bool getFatalWarnings(); diff --git a/llvm/lib/CodeGen/LLVMTargetMachine.cpp b/llvm/lib/CodeGen/LLVMTargetMachine.cpp --- a/llvm/lib/CodeGen/LLVMTargetMachine.cpp +++ b/llvm/lib/CodeGen/LLVMTargetMachine.cpp @@ -264,6 +264,9 @@ "Cannot emit MC with limited codegen pipeline"); Ctx = &MMIWP->getMMI().getContext(); + // libunwind is unable to load compact unwind dynamically, so we must generate + // DWARF unwind info for the JIT. + Options.MCOptions.EmitDwarfUnwind = EmitDwarfUnwindType::Always; if (Options.MCOptions.MCSaveTempLabels) Ctx->setAllowTemporaryLabels(false); diff --git a/llvm/lib/CodeGen/MachineModuleInfo.cpp b/llvm/lib/CodeGen/MachineModuleInfo.cpp --- a/llvm/lib/CodeGen/MachineModuleInfo.cpp +++ b/llvm/lib/CodeGen/MachineModuleInfo.cpp @@ -60,7 +60,7 @@ : TM(std::move(MMI.TM)), Context(MMI.TM.getTargetTriple(), MMI.TM.getMCAsmInfo(), MMI.TM.getMCRegisterInfo(), MMI.TM.getMCSubtargetInfo(), nullptr, - nullptr, false), + &MMI.TM.Options.MCOptions, false), MachineFunctions(std::move(MMI.MachineFunctions)) { Context.setObjectFileInfo(MMI.TM.getObjFileLowering()); ObjFileMMI = MMI.ObjFileMMI; @@ -72,7 +72,7 @@ MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM) : TM(*TM), Context(TM->getTargetTriple(), TM->getMCAsmInfo(), TM->getMCRegisterInfo(), TM->getMCSubtargetInfo(), - nullptr, nullptr, false) { + nullptr, &TM->Options.MCOptions, false) { Context.setObjectFileInfo(TM->getObjFileLowering()); initialize(); } @@ -81,7 +81,7 @@ MCContext *ExtContext) : TM(*TM), Context(TM->getTargetTriple(), TM->getMCAsmInfo(), TM->getMCRegisterInfo(), TM->getMCSubtargetInfo(), - nullptr, nullptr, false), + nullptr, &TM->Options.MCOptions, false), ExternalContext(ExtContext) { Context.setObjectFileInfo(TM->getObjFileLowering()); initialize(); diff --git a/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp --- a/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp +++ b/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp @@ -19,6 +19,7 @@ #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Mangler.h" #include "llvm/IR/Module.h" +#include "llvm/MC/MCContext.h" #include "llvm/Object/Archive.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/DynamicLibrary.h" diff --git a/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp b/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp --- a/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp +++ b/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp @@ -12,6 +12,7 @@ #include "llvm/ExecutionEngine/ObjectCache.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" +#include "llvm/MC/MCContext.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp @@ -95,18 +95,16 @@ // and projects/libunwind/src/UnwindLevel1-gcc-ext.c. const char *P = (const char *)Addr; const char *End = P + Size; - do { + while (P != End) P = processFDE(P, false); - } while(P != End); } void RTDyldMemoryManager::deregisterEHFramesInProcess(uint8_t *Addr, size_t Size) { const char *P = (const char *)Addr; const char *End = P + Size; - do { + while (P != End) P = processFDE(P, true); - } while(P != End); } #else diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp --- a/llvm/lib/MC/MCContext.cpp +++ b/llvm/lib/MC/MCContext.cpp @@ -877,6 +877,12 @@ // Dwarf Management //===----------------------------------------------------------------------===// +EmitDwarfUnwindType MCContext::emitDwarfUnwindInfo() const { + if (!TargetOptions) + return EmitDwarfUnwindType::Default; + return TargetOptions->EmitDwarfUnwind; +} + void MCContext::setGenDwarfRootFile(StringRef InputFileName, StringRef Buffer) { // MCDwarf needs the root file as well as the compilation directory. // If we find a '.file 0' directive that will supersede these values. diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp --- a/llvm/lib/MC/MCDwarf.cpp +++ b/llvm/lib/MC/MCDwarf.cpp @@ -1842,8 +1842,6 @@ void MCDwarfFrameEmitter::Emit(MCObjectStreamer &Streamer, MCAsmBackend *MAB, bool IsEH) { - Streamer.generateCompactUnwindEncodings(MAB); - MCContext &Context = Streamer.getContext(); const MCObjectFileInfo *MOFI = Context.getObjectFileInfo(); const MCAsmInfo *AsmInfo = Context.getAsmInfo(); @@ -1853,6 +1851,7 @@ // Emit the compact unwind info if available. bool NeedsEHFrameSection = !MOFI->getSupportsCompactUnwindWithoutEHFrame(); if (IsEH && MOFI->getCompactUnwindSection()) { + Streamer.generateCompactUnwindEncodings(MAB); bool SectionEmitted = false; for (const MCDwarfFrameInfo &Frame : FrameArray) { if (Frame.CompactUnwindEncoding == 0) continue; diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp --- a/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/llvm/lib/MC/MCObjectFileInfo.cpp @@ -64,8 +64,18 @@ (T.getArch() == Triple::aarch64 || T.getArch() == Triple::aarch64_32)) SupportsCompactUnwindWithoutEHFrame = true; - if (T.isWatchABI()) + switch (Ctx->emitDwarfUnwindInfo()) { + case EmitDwarfUnwindType::Always: + OmitDwarfIfHaveCompactUnwind = false; + break; + case EmitDwarfUnwindType::NoCompactUnwind: OmitDwarfIfHaveCompactUnwind = true; + break; + case EmitDwarfUnwindType::Default: + OmitDwarfIfHaveCompactUnwind = + T.isWatchABI() || SupportsCompactUnwindWithoutEHFrame; + break; + } FDECFIEncoding = dwarf::DW_EH_PE_pcrel; diff --git a/llvm/lib/MC/MCTargetOptions.cpp b/llvm/lib/MC/MCTargetOptions.cpp --- a/llvm/lib/MC/MCTargetOptions.cpp +++ b/llvm/lib/MC/MCTargetOptions.cpp @@ -17,6 +17,7 @@ MCSaveTempLabels(false), MCIncrementalLinkerCompatible(false), ShowMCEncoding(false), ShowMCInst(false), AsmVerbose(false), PreserveAsmComments(true), Dwarf64(false), + EmitDwarfUnwind(EmitDwarfUnwindType::Default), MCUseDwarfDirectory(DefaultDwarfDirectory) {} StringRef MCTargetOptions::getABIName() const { diff --git a/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp b/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp --- a/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp +++ b/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp @@ -1,5 +1,4 @@ -//===-- MCTargetOptionsCommandFlags.cpp --------------------------*- C++ -//-*-===// +//===-- MCTargetOptionsCommandFlags.cpp -----------------------*- C++ //-*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -39,6 +38,7 @@ MCOPT(bool, IncrementalLinkerCompatible) MCOPT(int, DwarfVersion) MCOPT(bool, Dwarf64) +MCOPT(EmitDwarfUnwindType, EmitDwarfUnwind) MCOPT(bool, ShowMCInst) MCOPT(bool, FatalWarnings) MCOPT(bool, NoWarn) @@ -73,6 +73,19 @@ cl::desc("Generate debugging info in the 64-bit DWARF format")); MCBINDOPT(Dwarf64); + static cl::opt EmitDwarfUnwind( + "emit-dwarf-unwind", cl::desc("Whether to emit DWARF EH frame entries."), + cl::init(EmitDwarfUnwindType::Default), + cl::values(clEnumValN(EmitDwarfUnwindType::Always, "always", + "Always emit EH frame entries"), + clEnumValN(EmitDwarfUnwindType::NoCompactUnwind, + "no-compact-unwind", + "Only emit EH frame entries when compact unwind is " + "not available"), + clEnumValN(EmitDwarfUnwindType::Default, "default", + "Use target platform default"))); + MCBINDOPT(EmitDwarfUnwind); + static cl::opt ShowMCInst( "asm-show-inst", cl::desc("Emit internal instruction representation to assembly file")); @@ -116,5 +129,7 @@ Options.MCNoWarn = getNoWarn(); Options.MCNoDeprecatedWarn = getNoDeprecatedWarn(); Options.MCNoTypeCheck = getNoTypeCheck(); + Options.EmitDwarfUnwind = getEmitDwarfUnwind(); + return Options; } diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp --- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -1377,7 +1377,7 @@ default: // Any other CFI directives indicate a frame that we aren't prepared // to represent via compact unwind, so just bail out. - return 0; + return CU::UNWIND_MODE_DWARF; case MCCFIInstruction::OpDefCfaRegister: { // Defines a frame pointer. E.g. // @@ -1391,7 +1391,7 @@ // generate a compact unwinding representation, so bail out. if (*MRI.getLLVMRegNum(Inst.getRegister(), true) != (Is64Bit ? X86::RBP : X86::EBP)) - return 0; + return CU::UNWIND_MODE_DWARF; // Reset the counts. memset(SavedRegs, 0, sizeof(SavedRegs)); diff --git a/llvm/test/MC/MachO/emit-dwarf-unwind.s b/llvm/test/MC/MachO/emit-dwarf-unwind.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/MachO/emit-dwarf-unwind.s @@ -0,0 +1,33 @@ +// RUN: rm -rf %t; mkdir %t +// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj -o %t/x86_64.o +// RUN: llvm-objdump --macho --dwarf=frames %t/x86_64.o | FileCheck %s --check-prefix TWO-FDES +// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj -o %t/arm64.o +// RUN: llvm-objdump --macho --dwarf=frames %t/arm64.o | FileCheck %s --check-prefix ONE-FDE +// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind no-compact-unwind -o %t/x86_64-no-dwarf.o +// RUN: llvm-objdump --macho --dwarf=frames %t/x86_64-no-dwarf.o | FileCheck %s --check-prefix ONE-FDE +// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind always -o %t/arm64-dwarf.o +// RUN: llvm-objdump --macho --dwarf=frames %t/arm64-dwarf.o | FileCheck %s --check-prefix TWO-FDES + +// TWO-FDES: FDE +// TWO-FDES: FDE + +// ONE-FDE-NOT: FDE +// ONE-FDE: FDE +// ONE-FDE-NOT: FDE + +_main: + .cfi_startproc + .cfi_def_cfa_offset 16 + ret + .cfi_endproc + +_foo: + .cfi_startproc + .cfi_def_cfa_offset 16 + /// This encodes DW_CFA_GNU_args_size which cannot be expressed using compact + /// unwind, so we must use DWARf unwind for this function. + .cfi_escape 0x2e, 0x10 + ret + .cfi_endproc + +.subsections_via_symbols diff --git a/llvm/test/MC/X86/compact-unwind-mode-dwarf.s b/llvm/test/MC/X86/compact-unwind-mode-dwarf.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/X86/compact-unwind-mode-dwarf.s @@ -0,0 +1,50 @@ +// RUN: llvm-mc -triple x86_64-apple-macos10.6 -filetype=obj %s -o %t.o +// RUN: llvm-objdump --macho --unwind-info --dwarf=frames %t.o | FileCheck %s + +/// For functions whose unwind info cannot be encoded with compact unwind, make +/// sure that we encode them using DWARF unwind, and make sure we emit a compact +/// unwind entry that indicates that a DWARF encoding is being used. + +_f: + .cfi_startproc + ## This encodes DW_CFA_GNU_args_size which cannot be expressed using compact + ## unwind, so we must use DWARF unwind instead. + .cfi_escape 0x2e, 0x10 + ret + .cfi_endproc + +_g: + .cfi_startproc + ## This encodes DW_CFA_GNU_args_size which cannot be expressed using compact + ## unwind, so we must use DWARF unwind instead. + .cfi_escape 0x2e, 0x10 + ret + .cfi_endproc + +// CHECK: Contents of __compact_unwind section: +// CHECK: Entry at offset 0x0: +// CHECK: start: 0x[[#%x,F:]] _f +// CHECK: length: 0x1 +// CHECK: compact encoding: 0x04000000 +// CHECK: Entry at offset 0x20: +// CHECK: start: 0x[[#%x,G:]] _g +// CHECK: length: 0x1 +// CHECK: compact encoding: 0x04000000 + +// CHECK: .eh_frame contents: +// CHECK: 00000000 00000014 00000000 CIE +// CHECK: Format: DWARF32 +// CHECK: Version: 1 +// CHECK: Augmentation: "zR" +// CHECK: Code alignment factor: 1 +// CHECK: Data alignment factor: -8 +// CHECK: Return address column: 16 +// CHECK: Augmentation data: 10 + +// CHECK: FDE cie=00000000 pc=[[#%.8x,F]]... +// CHECK: Format: DWARF32 +// CHECK: DW_CFA_GNU_args_size: +16 + +// CHECK: FDE cie=00000000 pc=[[#%.8x,G]]... +// CHECK: Format: DWARF32 +// CHECK: DW_CFA_GNU_args_size: +16