[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