[llvm] r330884 - [codeview] Ignore .cv_loc directives at the end of a function

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 25 16:34:15 PDT 2018


Author: rnk
Date: Wed Apr 25 16:34:15 2018
New Revision: 330884

URL: http://llvm.org/viewvc/llvm-project?rev=330884&view=rev
Log:
[codeview] Ignore .cv_loc directives at the end of a function

If no data or instructions are emitted after a location directive, we
should clear the cv_loc when we change sections, or it will be emitted
at the beginning of the next section. This violates our invariant that
all .cv_loc directives belong to the same section. Add clearer
assertions for this.

Added:
    llvm/trunk/test/MC/COFF/cv-loc-unreachable.s
Modified:
    llvm/trunk/include/llvm/MC/MCContext.h
    llvm/trunk/lib/MC/MCCodeView.cpp
    llvm/trunk/lib/MC/MCContext.cpp
    llvm/trunk/lib/MC/MCObjectStreamer.cpp

Modified: llvm/trunk/include/llvm/MC/MCContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCContext.h?rev=330884&r1=330883&r2=330884&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCContext.h (original)
+++ llvm/trunk/include/llvm/MC/MCContext.h Wed Apr 25 16:34:15 2018
@@ -295,6 +295,10 @@ namespace llvm {
 
     CodeViewContext &getCVContext();
 
+    /// Clear the current cv_loc, if there is one. Avoids lazily creating a
+    /// CodeViewContext if none is needed.
+    void clearCVLocSeen();
+
     void setAllowTemporaryLabels(bool Value) { AllowTemporaryLabels = Value; }
     void setUseNamesOnTempLabels(bool Value) { UseNamesOnTempLabels = Value; }
 

Modified: llvm/trunk/lib/MC/MCCodeView.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCCodeView.cpp?rev=330884&r1=330883&r2=330884&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCCodeView.cpp (original)
+++ llvm/trunk/lib/MC/MCCodeView.cpp Wed Apr 25 16:34:15 2018
@@ -472,6 +472,19 @@ void CodeViewContext::encodeInlineLineTa
   if (Locs.empty())
     return;
 
+  // Check that the locations are all in the same section.
+#ifndef NDEBUG
+  const MCSection *FirstSec = &Locs.front().getLabel()->getSection();
+  for (const MCCVLineEntry &Loc : Locs) {
+    if (&Loc.getLabel()->getSection() != FirstSec) {
+      errs() << ".cv_loc " << Loc.getFunctionId() << ' ' << Loc.getFileNum()
+             << ' ' << Loc.getLine() << ' ' << Loc.getColumn()
+             << " is in the wrong section\n";
+      llvm_unreachable(".cv_loc crosses sections");
+    }
+  }
+#endif
+
   // Make an artificial start location using the function start and the inlinee
   // lines start location information. All deltas start relative to this
   // location.

Modified: llvm/trunk/lib/MC/MCContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCContext.cpp?rev=330884&r1=330883&r2=330884&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCContext.cpp (original)
+++ llvm/trunk/lib/MC/MCContext.cpp Wed Apr 25 16:34:15 2018
@@ -570,6 +570,11 @@ CodeViewContext &MCContext::getCVContext
   return *CVContext.get();
 }
 
+void MCContext::clearCVLocSeen() {
+  if (CVContext)
+    CVContext->clearCVLocSeen();
+}
+
 //===----------------------------------------------------------------------===//
 // Error Reporting
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/lib/MC/MCObjectStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCObjectStreamer.cpp?rev=330884&r1=330883&r2=330884&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCObjectStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCObjectStreamer.cpp Wed Apr 25 16:34:15 2018
@@ -247,6 +247,7 @@ bool MCObjectStreamer::changeSectionImpl
                                          const MCExpr *Subsection) {
   assert(Section && "Cannot switch to a null section!");
   flushPendingLabels(nullptr);
+  getContext().clearCVLocSeen();
   getContext().clearDwarfLocSeen();
 
   bool Created = getAssembler().registerSection(*Section);

Added: llvm/trunk/test/MC/COFF/cv-loc-unreachable.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/COFF/cv-loc-unreachable.s?rev=330884&view=auto
==============================================================================
--- llvm/trunk/test/MC/COFF/cv-loc-unreachable.s (added)
+++ llvm/trunk/test/MC/COFF/cv-loc-unreachable.s Wed Apr 25 16:34:15 2018
@@ -0,0 +1,183 @@
+# RUN: llvm-mc < %s -triple=i686-pc-win32 -filetype=obj | llvm-readobj - -codeview | FileCheck %s
+
+# Original source, slightly modified with an extra .cv_loc directive (at EXTRA
+# below) that was causing assertions:
+#
+# void __declspec(noreturn) __declspec(dllimport) exit(int);
+# int unlikely();
+# static inline void do_exit() {
+#   if (unlikely()) {
+#     exit(32);
+#   }
+# }
+# void callit() {
+#   do_exit();
+# }
+
+# We should *not* see t.cpp:6 in the inline line table because we change
+# sections before the next instruction. We should only see t.cpp:5.
+
+# CHECK-LABEL: InlineeSourceLine {
+# CHECK:   Inlinee: do_exit (0x1002)
+# CHECK:   FileID: C:\src\llvm-project\build\t.cpp (0x0)
+# CHECK:   SourceLineNum: 3
+# CHECK: }
+
+# CHECK-LABEL: InlineSiteSym {
+# CHECK:   Kind: S_INLINESITE (0x114D)
+# CHECK:   Inlinee: do_exit (0x1002)
+# CHECK:   BinaryAnnotations [
+# CHECK-NEXT:     ChangeLineOffset: 1
+# CHECK-NEXT:     ChangeCodeLength: 0x9
+# CHECK-NEXT:     ChangeCodeOffsetAndLineOffset: {CodeOffset: 0x1, LineOffset: 1}
+# CHECK-NEXT:     ChangeCodeLength: 0x8
+# CHECK-NEXT:   ]
+# CHECK: }
+
+	.text
+	.def	 _callit; .scl	2; .type	32; .endef
+	.globl	_callit                 # -- Begin function callit
+_callit:                                # @callit
+Lfunc_begin0:
+	.cv_func_id 0
+	.cv_fpo_proc	_callit 0
+# %bb.0:                                # %entry
+	.cv_file	1 "C:\\src\\llvm-project\\build\\t.cpp" "0BC092F354CE14FDC2FA78F8EDE7426E" 1
+	.cv_inline_site_id 1 within 0 inlined_at 1 9 0
+	.cv_loc	1 1 4 0 is_stmt 0       # t.cpp:4:0
+	calll	_unlikely
+	testl	%eax, %eax
+	jne	LBB0_1
+Ltmp0:
+# %bb.2:                                # %do_exit.exit
+	.cv_loc	0 1 10 0                # t.cpp:10:0
+	retl
+LBB0_1:                                 # %if.then.i
+Ltmp1:
+	.cv_loc	1 1 5 0                 # t.cpp:5:0
+	pushl	$32
+	calll	*__imp__exit
+	# EXTRA
+	.cv_loc	1 1 6 0                 # t.cpp:6:0
+Ltmp2:
+	.cv_fpo_endproc
+Lfunc_end0:
+                                        # -- End function
+
+	.section	.debug$S,"dr"
+	.p2align	2
+	.long	4                       # Debug section magic
+	.long	241
+	.long	Ltmp4-Ltmp3             # Subsection size
+Ltmp3:
+	.short	Ltmp6-Ltmp5             # Record length
+Ltmp5:
+	.short	4412                    # Record kind: S_COMPILE3
+	.long	0                       # Flags and language
+	.short	7                       # CPUType
+	.short	7                       # Frontend version
+	.short	0
+	.short	0
+	.short	0
+	.short	7000                    # Backend version
+	.short	0
+	.short	0
+	.short	0
+	.asciz	"clang version 7.0.0 "  # Null-terminated compiler version string
+Ltmp6:
+Ltmp4:
+	.p2align	2
+	.long	246                     # Inlinee lines subsection
+	.long	Ltmp8-Ltmp7             # Subsection size
+Ltmp7:
+	.long	0                       # Inlinee lines signature
+
+                                        # Inlined function do_exit starts at t.cpp:3
+	.long	4098                    # Type index of inlined function
+	.cv_filechecksumoffset	1       # Offset into filechecksum table
+	.long	3                       # Starting line number
+Ltmp8:
+	.p2align	2
+	.cv_fpo_data	_callit
+	.long	241                     # Symbol subsection for callit
+	.long	Ltmp10-Ltmp9            # Subsection size
+Ltmp9:
+	.short	Ltmp12-Ltmp11           # Record length
+Ltmp11:
+	.short	4423                    # Record kind: S_GPROC32_ID
+	.long	0                       # PtrParent
+	.long	0                       # PtrEnd
+	.long	0                       # PtrNext
+	.long	Lfunc_end0-_callit      # Code size
+	.long	0                       # Offset after prologue
+	.long	0                       # Offset before epilogue
+	.long	4099                    # Function type index
+	.secrel32	_callit         # Function section relative address
+	.secidx	_callit                 # Function section index
+	.byte	0                       # Flags
+	.asciz	"callit"                # Function name
+Ltmp12:
+	.short	Ltmp14-Ltmp13           # Record length
+Ltmp13:
+	.short	4429                    # Record kind: S_INLINESITE
+	.long	0                       # PtrParent
+	.long	0                       # PtrEnd
+	.long	4098                    # Inlinee type index
+	.cv_inline_linetable	1 1 3 Lfunc_begin0 Lfunc_end0
+Ltmp14:
+	.short	2                       # Record length
+	.short	4430                    # Record kind: S_INLINESITE_END
+	.short	2                       # Record length
+	.short	4431                    # Record kind: S_PROC_ID_END
+Ltmp10:
+	.p2align	2
+	.cv_linetable	0, _callit, Lfunc_end0
+	.cv_filechecksums               # File index to string table offset subsection
+	.cv_stringtable                 # String table
+	.section	.debug$T,"dr"
+	.p2align	2
+	.long	4                       # Debug section magic
+	# ArgList (0x1000) {
+	#   TypeLeafKind: LF_ARGLIST (0x1201)
+	#   NumArgs: 0
+	#   Arguments [
+	#   ]
+	# }
+	.byte	0x06, 0x00, 0x01, 0x12
+	.byte	0x00, 0x00, 0x00, 0x00
+	# Procedure (0x1001) {
+	#   TypeLeafKind: LF_PROCEDURE (0x1008)
+	#   ReturnType: void (0x3)
+	#   CallingConvention: NearC (0x0)
+	#   FunctionOptions [ (0x0)
+	#   ]
+	#   NumParameters: 0
+	#   ArgListType: () (0x1000)
+	# }
+	.byte	0x0e, 0x00, 0x08, 0x10
+	.byte	0x03, 0x00, 0x00, 0x00
+	.byte	0x00, 0x00, 0x00, 0x00
+	.byte	0x00, 0x10, 0x00, 0x00
+	# FuncId (0x1002) {
+	#   TypeLeafKind: LF_FUNC_ID (0x1601)
+	#   ParentScope: 0x0
+	#   FunctionType: void () (0x1001)
+	#   Name: do_exit
+	# }
+	.byte	0x12, 0x00, 0x01, 0x16
+	.byte	0x00, 0x00, 0x00, 0x00
+	.byte	0x01, 0x10, 0x00, 0x00
+	.byte	0x64, 0x6f, 0x5f, 0x65
+	.byte	0x78, 0x69, 0x74, 0x00
+	# FuncId (0x1003) {
+	#   TypeLeafKind: LF_FUNC_ID (0x1601)
+	#   ParentScope: 0x0
+	#   FunctionType: void () (0x1001)
+	#   Name: callit
+	# }
+	.byte	0x12, 0x00, 0x01, 0x16
+	.byte	0x00, 0x00, 0x00, 0x00
+	.byte	0x01, 0x10, 0x00, 0x00
+	.byte	0x63, 0x61, 0x6c, 0x6c
+	.byte	0x69, 0x74, 0x00, 0xf1
+




More information about the llvm-commits mailing list