[llvm] becbbb7 - Round up zero-sized symbols to 1 byte in `.debug_aranges` (without breaking other logic).

Alexander Yermolovich via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 27 10:01:55 PDT 2022


Author: Patrick Walton
Date: 2022-06-27T10:01:03-07:00
New Revision: becbbb7e3c8141b3346211faf9359f629cbf4e4d

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

LOG: Round up zero-sized symbols to 1 byte in `.debug_aranges` (without breaking other logic).

This commit modifies the AsmPrinter to avoid emitting any zero-sized symbols to
the .debug_aranges table, by rounding their size up to 1. Entries with zero
length violate the DWARF 5 spec, which states:

> Each descriptor is a triple consisting of a segment selector, the beginning
> address within that segment of a range of text or data covered by some entry
> owned by the corresponding compilation unit, followed by the non-zero length
> of that range.

In practice, these zero-sized entries produce annoying warnings in lld and
cause GNU binutils to truncate the table when parsing it.

Other parts of LLVM, such as DWARFDebugARanges in the DebugInfo module
(specifically the appendRange method), already avoid emitting zero-sized
symbols to .debug_aranges, but not comprehensively in the AsmPrinter. In fact,
the AsmPrinter does try to avoid emitting such zero-sized symbols when labels
aren't involved, but doesn't when the symbol to emitted is a difference of two
labels; this patch extends that logic to handle the case in which the symbol is
defined via labels.

Furthermore, this patch fixes a bug in which `available_externally` symbols
would cause unpredictable values to be emitted into the `.debug_aranges` table
under certain circumstances. In practice I don't believe that this caused
issues up until now, but the root cause of this bug--an invalid DenseMap
lookup--triggered failures in Chromium when combined with an earlier version of
this patch. Therefore, this patch fixes that bug too.

This is a revised version of diff D126257, which was reverted due to breaking
tests. The now-reverted version of this patch didn't distinguish between
symbols that didn't have their size reported to the DwarfDebug handler and
those that had their size reported to be zero. This new version of the patch
instead restricts the special handling only to the symbols whose size is
definitively known to be zero.

Reviewed By: dblaikie

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

Added: 
    llvm/test/CodeGen/X86/dwarf-aranges-available-externally.ll
    llvm/test/CodeGen/X86/dwarf-aranges-zero-size.ll

Modified: 
    llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 174ab14e90b7e..866338a949f3f 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -3042,15 +3042,22 @@ void DwarfDebug::emitDebugARanges() {
     for (const ArangeSpan &Span : List) {
       Asm->emitLabelReference(Span.Start, PtrSize);
 
-      // Calculate the size as being from the span start to it's end.
-      if (Span.End) {
+      // Calculate the size as being from the span start to its end.
+      //
+      // If the size is zero, then round it up to one byte. The DWARF
+      // specification requires that entries in this table have nonzero
+      // lengths.
+      auto SizeRef = SymSize.find(Span.Start);
+      if ((SizeRef == SymSize.end() || SizeRef->second != 0) && Span.End) {
         Asm->emitLabelDifference(Span.End, Span.Start, PtrSize);
       } else {
         // For symbols without an end marker (e.g. common), we
         // write a single arange entry containing just that one symbol.
-        uint64_t Size = SymSize[Span.Start];
-        if (Size == 0)
+        uint64_t Size;
+        if (SizeRef == SymSize.end() || SizeRef->second == 0)
           Size = 1;
+        else
+          Size = SizeRef->second;
 
         Asm->OutStreamer->emitIntValue(Size, PtrSize);
       }

diff  --git a/llvm/test/CodeGen/X86/dwarf-aranges-available-externally.ll b/llvm/test/CodeGen/X86/dwarf-aranges-available-externally.ll
new file mode 100644
index 0000000000000..839f462dbdc81
--- /dev/null
+++ b/llvm/test/CodeGen/X86/dwarf-aranges-available-externally.ll
@@ -0,0 +1,71 @@
+; Ensures that the compiler doesn't assert when DWARF aranges are enabled in the presence of
+; `available_externally` constants.
+
+; Generated from the following C++ source:
+;
+;   template <typename T>
+;   struct Baz {
+;       static constexpr int boo = int(-1);
+;   };
+;
+;   extern template struct Baz<char>;
+;
+;   void bar(const int& a);
+;
+;   void foo() {
+;       bar(Baz<char>::boo);
+;   }
+;
+; Compiled with:
+;
+;     $ clang -cc1 -triple=x86_64-unknown-linux-gnu -debug-info-kind=standalone \
+;       -mllvm -generate-arange-section -std=c++17 foo.cpp
+
+; RUN: llc --generate-arange-section < %s
+
+; ModuleID = 'reduced2.cpp'
+source_filename = "reduced2.cpp"
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+ at _ZN3BazIcE3booE = available_externally constant i32 -1, align 4, !dbg !0
+
+; Function Attrs: mustprogress noinline nounwind optnone
+define dso_local void @_Z3foov() #0 !dbg !17 {
+entry:
+  call void @_Z3barRKi(ptr noundef nonnull align 4 dereferenceable(4) @_ZN3BazIcE3booE), !dbg !21
+  ret void, !dbg !22
+}
+
+declare void @_Z3barRKi(ptr noundef nonnull align 4 dereferenceable(4)) #1
+
+attributes #0 = { mustprogress noinline nounwind optnone "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
+attributes #1 = { "frame-pointer"="none" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!14, !15}
+!llvm.ident = !{!16}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "boo", linkageName: "_ZN3BazIcE3booE", scope: !2, file: !5, line: 3, type: !6, isLocal: false, isDefinition: true, declaration: !8)
+!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, producer: "clang version 15.0.0 (https://github.com/llvm/llvm-project.git 2f52a868225755ebfa5242992d3a650ac6aadce7)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None)
+!3 = !DIFile(filename: "<stdin>", directory: "/Users/pcwalton/Downloads")
+!4 = !{!0}
+!5 = !DIFile(filename: "reduced2.cpp", directory: "/Users/pcwalton/Downloads")
+!6 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !7)
+!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!8 = !DIDerivedType(tag: DW_TAG_member, name: "boo", scope: !9, file: !5, line: 3, baseType: !6, flags: DIFlagStaticMember, extraData: i32 -1)
+!9 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Baz<char>", file: !5, line: 6, size: 8, flags: DIFlagTypePassByValue, elements: !10, templateParams: !11, identifier: "_ZTS3BazIcE")
+!10 = !{!8}
+!11 = !{!12}
+!12 = !DITemplateTypeParameter(name: "T", type: !13)
+!13 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
+!14 = !{i32 2, !"Debug Info Version", i32 3}
+!15 = !{i32 1, !"wchar_size", i32 4}
+!16 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project.git 2f52a868225755ebfa5242992d3a650ac6aadce7)"}
+!17 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !5, file: !5, line: 10, type: !18, scopeLine: 10, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !20)
+!18 = !DISubroutineType(types: !19)
+!19 = !{null}
+!20 = !{}
+!21 = !DILocation(line: 11, column: 3, scope: !17)
+!22 = !DILocation(line: 12, column: 1, scope: !17)

diff  --git a/llvm/test/CodeGen/X86/dwarf-aranges-zero-size.ll b/llvm/test/CodeGen/X86/dwarf-aranges-zero-size.ll
new file mode 100644
index 0000000000000..022f6e6faa10d
--- /dev/null
+++ b/llvm/test/CodeGen/X86/dwarf-aranges-zero-size.ll
@@ -0,0 +1,39 @@
+; Ensures that the AsmPrinter rounds up zero-sized symbols in `.debug_aranges` to one byte.
+
+; Generated from the following Rust source:
+;
+;     pub static EXAMPLE: () = ();
+;
+; Compiled with:
+;
+;     $ rustc --crate-type=lib --target=x86_64-unknown-linux-gnu --emit=llvm-ir -g dwarf-aranges-zero-size.rs
+
+; RUN: llc --generate-arange-section < %s | FileCheck %s
+; CHECK: .section .debug_aranges
+; CHECK: .quad _ZN23dwarf_aranges_zero_size7EXAMPLE17h8ab19f2b0c3b238dE
+; CHECK-NEXT: .quad 1
+; CHECK: .section
+
+; ModuleID = 'dwarf_aranges_zero_size.fbc28187-cgu.0'
+source_filename = "dwarf_aranges_zero_size.fbc28187-cgu.0"
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+ at _ZN23dwarf_aranges_zero_size7EXAMPLE17h8ab19f2b0c3b238dE = constant <{ [0 x i8] }> zeroinitializer, align 1, !dbg !0
+ at __rustc_debug_gdb_scripts_section__ = linkonce_odr unnamed_addr constant [34 x i8] c"\01gdb_load_rust_pretty_printers.py\00", section ".debug_gdb_scripts", align 1
+
+!llvm.module.flags = !{!5, !6, !7}
+!llvm.dbg.cu = !{!8}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "EXAMPLE", linkageName: "_ZN23dwarf_aranges_zero_size7EXAMPLE17h8ab19f2b0c3b238dE", scope: !2, file: !3, line: 1, type: !4, isLocal: false, isDefinition: true, align: 8)
+!2 = !DINamespace(name: "dwarf_aranges_zero_size", scope: null)
+!3 = !DIFile(filename: "dwarf-aranges-zero-size.rs", directory: "/Users/pcwalton/Desktop", checksumkind: CSK_MD5, checksum: "c2d51547bfaf5562b9c9061311fe4140")
+!4 = !DIBasicType(name: "()", encoding: DW_ATE_unsigned)
+!5 = !{i32 7, !"PIC Level", i32 2}
+!6 = !{i32 2, !"RtLibUseGOT", i32 1}
+!7 = !{i32 2, !"Debug Info Version", i32 3}
+!8 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !9, producer: "clang LLVM (rustc version 1.60.0-nightly (0c292c966 2022-02-08))", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !10, globals: !11)
+!9 = !DIFile(filename: "dwarf-aranges-zero-size.rs/@/dwarf_aranges_zero_size.fbc28187-cgu.0", directory: "/Users/pcwalton/Desktop")
+!10 = !{}
+!11 = !{!0}


        


More information about the llvm-commits mailing list