]> granicus.if.org Git - llvm/commitdiff
Reapply "[CodeGen] Fix invalid DWARF info on Win64"
authorKeno Fischer <kfischer@college.harvard.edu>
Mon, 2 Jan 2017 03:00:19 +0000 (03:00 +0000)
committerKeno Fischer <kfischer@college.harvard.edu>
Mon, 2 Jan 2017 03:00:19 +0000 (03:00 +0000)
This reapplies rL289013 (reverted in rL289014) with the fixes identified
in D21731. Should hopefully pass the buildbots this time.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@290809 91177308-0d34-0410-b5e6-96231b3b80d8

13 files changed:
docs/Extensions.rst
include/llvm/MC/MCStreamer.h
include/llvm/MC/MCWinCOFFStreamer.h
lib/CodeGen/AsmPrinter/AsmPrinter.cpp
lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
lib/CodeGen/AsmPrinter/DIE.cpp
lib/MC/MCAsmStreamer.cpp
lib/MC/MCCodeView.cpp
lib/MC/MCParser/COFFAsmParser.cpp
lib/MC/MCStreamer.cpp
lib/MC/WinCOFFStreamer.cpp
test/DebugInfo/X86/ref_addr_relocation.ll

index 6c50abf192f2d1e0e474a59929aeb33be46a582e..850c42750911f6871f6b03b344f29ed00bc96346 100644 (file)
@@ -67,7 +67,7 @@ the target.  It corresponds to the COFF relocation types
     .long 4
     .long 242
     .long 40
-    .secrel32 _function_name
+    .secrel32 _function_name + 0
     .secidx   _function_name
     ...
 
index 471a5d4a9edf0dcd243265f14780423aec896ecc..41f00a24dfbfb03ff161e31bbd27c5e4356a6d98 100644 (file)
@@ -475,7 +475,7 @@ public:
   /// \brief Emits a COFF section relative relocation.
   ///
   /// \param Symbol - Symbol the section relative relocation should point to.
-  virtual void EmitCOFFSecRel32(MCSymbol const *Symbol);
+  virtual void EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset);
 
   /// \brief Emit an ELF .size directive.
   ///
index fe1ada9b9e5b94e1c708f675b82e066af1f02ea7..63e44f2e67d6791cb8e7a0d7b13a5a3c2cfcd1e4 100644 (file)
@@ -52,7 +52,7 @@ public:
   void EndCOFFSymbolDef() override;
   void EmitCOFFSafeSEH(MCSymbol const *Symbol) override;
   void EmitCOFFSectionIndex(MCSymbol const *Symbol) override;
-  void EmitCOFFSecRel32(MCSymbol const *Symbol) override;
+  void EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) override;
   void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
                         unsigned ByteAlignment) override;
   void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
index f0537e04165f9cf2d587013e93e0cbd6148422b2..de0a4f0befa1afe11ad59c7d855c84f645b202bd 100644 (file)
@@ -1689,7 +1689,9 @@ void AsmPrinter::EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset,
                                      unsigned Size,
                                      bool IsSectionRelative) const {
   if (MAI->needsDwarfSectionOffsetDirective() && IsSectionRelative) {
-    OutStreamer->EmitCOFFSecRel32(Label);
+    OutStreamer->EmitCOFFSecRel32(Label, Offset);
+    if (Size > 4)
+      OutStreamer->EmitZeros(Size - 4);
     return;
   }
 
index 6c1cc7e519eacb6013c94da05f3b4e21f621c3a7..0185c380cc394fe047f477da0593e059549cc9aa 100644 (file)
@@ -149,7 +149,7 @@ void AsmPrinter::emitDwarfSymbolReference(const MCSymbol *Label,
   if (!ForceOffset) {
     // On COFF targets, we have to emit the special .secrel32 directive.
     if (MAI->needsDwarfSectionOffsetDirective()) {
-      OutStreamer->EmitCOFFSecRel32(Label);
+      OutStreamer->EmitCOFFSecRel32(Label, /*Offset=*/0);
       return;
     }
 
index 8dde4a1031b05f6f6625c9accaad02e85a3b9cdb..408b34a3cdc013e23bad0207084355e014ad1e28 100644 (file)
@@ -801,7 +801,7 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
     OS.AddComment("Function type index");
     OS.EmitIntValue(getFuncIdForSubprogram(GV->getSubprogram()).getIndex(), 4);
     OS.AddComment("Function section relative address");
-    OS.EmitCOFFSecRel32(Fn);
+    OS.EmitCOFFSecRel32(Fn, /*Offset=*/0);
     OS.AddComment("Function section index");
     OS.EmitCOFFSectionIndex(Fn);
     OS.AddComment("Flags");
@@ -2279,7 +2279,7 @@ void CodeViewDebug::emitDebugInfoForGlobal(const DIGlobalVariable *DIGV,
   OS.AddComment("Type");
   OS.EmitIntValue(getCompleteTypeIndex(DIGV->getType()).getIndex(), 4);
   OS.AddComment("DataOffset");
-  OS.EmitCOFFSecRel32(GVSym);
+  OS.EmitCOFFSecRel32(GVSym, /*Offset=*/0);
   OS.AddComment("Segment");
   OS.EmitCOFFSectionIndex(GVSym);
   OS.AddComment("Name");
index 622e4dc92586596fd025c063a8cad523a485e892..8ae2f2487cadedf53a2cece681a75898e0540c6c 100644 (file)
@@ -495,7 +495,8 @@ void DIELabel::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const {
   AP->EmitLabelReference(Label, SizeOf(AP, Form),
                          Form == dwarf::DW_FORM_strp ||
                              Form == dwarf::DW_FORM_sec_offset ||
-                             Form == dwarf::DW_FORM_ref_addr);
+                             Form == dwarf::DW_FORM_ref_addr ||
+                             Form == dwarf::DW_FORM_data4);
 }
 
 /// SizeOf - Determine size of label value in bytes.
@@ -642,7 +643,7 @@ void DIEEntry::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const {
       MCSection *Section = Unit->getSection();
       if (Section) {
         const MCSymbol *SectionSym = Section->getBeginSymbol();
-        AP->EmitLabelPlusOffset(SectionSym, Addr, SizeOf(AP, Form));
+        AP->EmitLabelPlusOffset(SectionSym, Addr, SizeOf(AP, Form), true);
         return;
       }
     }
index 7227f1e25d866d604fa83d7625293e07859fa585..817009a6536385bba09bf27fe586e4ebcb8e75a2 100644 (file)
@@ -150,7 +150,7 @@ public:
   void EndCOFFSymbolDef() override;
   void EmitCOFFSafeSEH(MCSymbol const *Symbol) override;
   void EmitCOFFSectionIndex(MCSymbol const *Symbol) override;
-  void EmitCOFFSecRel32(MCSymbol const *Symbol) override;
+  void EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) override;
   void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
   void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
                         unsigned ByteAlignment) override;
@@ -617,9 +617,11 @@ void MCAsmStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {
   EmitEOL();
 }
 
-void MCAsmStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
+void MCAsmStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {
   OS << "\t.secrel32\t";
   Symbol->print(OS, MAI);
+  if (Offset != 0)
+    OS << '+' << Offset;
   EmitEOL();
 }
 
index 22bdba1ca2be0f51754f32b9bea53b60bc7008d9..3773542cf8a240428d92a1165795f13e36671417 100644 (file)
@@ -200,7 +200,7 @@ void CodeViewContext::emitLineTableForFunction(MCObjectStreamer &OS,
   OS.EmitIntValue(unsigned(ModuleSubstreamKind::Lines), 4);
   OS.emitAbsoluteSymbolDiff(LineEnd, LineBegin, 4);
   OS.EmitLabel(LineBegin);
-  OS.EmitCOFFSecRel32(FuncBegin);
+  OS.EmitCOFFSecRel32(FuncBegin, /*Offset=*/0);
   OS.EmitCOFFSectionIndex(FuncBegin);
 
   // Actual line info.
index 2c9f9eb0cda46413bce263f83b4da5cd201dfef2..f4114795a92d29b58b62d8030fc36f8d7f12603f 100644 (file)
@@ -455,13 +455,26 @@ bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) {
   if (getParser().parseIdentifier(SymbolID))
     return TokError("expected identifier in directive");
 
+  int64_t Offset = 0;
+  SMLoc OffsetLoc;
+  if (getLexer().is(AsmToken::Plus)) {
+    OffsetLoc = getLexer().getLoc();
+    if (getParser().parseAbsoluteExpression(Offset))
+      return true;
+  }
+
   if (getLexer().isNot(AsmToken::EndOfStatement))
     return TokError("unexpected token in directive");
 
+  if (Offset < 0 || Offset > UINT32_MAX)
+    return Error(OffsetLoc,
+                 "invalid '.secrel32' directive offset, can't be less "
+                 "than zero or greater than UINT32_MAX");
+
   MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
 
   Lex();
-  getStreamer().EmitCOFFSecRel32(Symbol);
+  getStreamer().EmitCOFFSecRel32(Symbol, Offset);
   return false;
 }
 
index 5cfa3ae80ceea59e541968c6c81f6f2decc65fec..fb28f856f671b08518fcde5b836eddf12000ca63 100644 (file)
@@ -125,7 +125,7 @@ void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
   if (!IsSectionRelative)
     EmitValueImpl(MCSymbolRefExpr::create(Sym, getContext()), Size);
   else
-    EmitCOFFSecRel32(Sym);
+    EmitCOFFSecRel32(Sym, /*Offset=*/0);
 }
 
 void MCStreamer::EmitDTPRel64Value(const MCExpr *Value) {
@@ -689,8 +689,7 @@ void MCStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) {
 void MCStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {
 }
 
-void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
-}
+void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {}
 
 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
 /// the specified string in the output .s file.  This capability is
index 5c6407ef1e5ca87deb2eb1408d4cefd60c2b20b0..6383d8794030790894fddd3007b1f9731c27b228 100644 (file)
@@ -195,11 +195,20 @@ void MCWinCOFFStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {
   DF->getContents().resize(DF->getContents().size() + 2, 0);
 }
 
-void MCWinCOFFStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
+void MCWinCOFFStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol,
+                                         uint64_t Offset) {
   MCDataFragment *DF = getOrCreateDataFragment();
-  const MCSymbolRefExpr *SRE = MCSymbolRefExpr::create(Symbol, getContext());
-  MCFixup Fixup = MCFixup::create(DF->getContents().size(), SRE, FK_SecRel_4);
+  // Create Symbol A for the relocation relative reference.
+  const MCExpr *MCE = MCSymbolRefExpr::create(Symbol, getContext());
+  // Add the constant offset, if given.
+  if (Offset)
+    MCE = MCBinaryExpr::createAdd(
+        MCE, MCConstantExpr::create(Offset, getContext()), getContext());
+  // Build the secrel32 relocation.
+  MCFixup Fixup = MCFixup::create(DF->getContents().size(), MCE, FK_SecRel_4);
+  // Record the relocation.
   DF->getFixups().push_back(Fixup);
+  // Emit 4 bytes (zeros) to the object file.
   DF->getContents().resize(DF->getContents().size() + 4, 0);
 }
 
index e049588ae9cf44ca6a470e1ae80fd55f75f2cf16..58fc236e6bbb6febc7c05043256d7575b04987ac 100644 (file)
@@ -1,10 +1,22 @@
-; RUN: llc -filetype=asm -O0 -mtriple=x86_64-linux-gnu < %s | FileCheck %s
-; RUN: llc -filetype=obj -O0 %s -mtriple=x86_64-linux-gnu -o %t
-; RUN: llvm-dwarfdump %t | FileCheck %s -check-prefix=CHECK-DWARF
+; RUN: llc -filetype=asm -O0 -mtriple=x86_64-linux-gnu < %s -dwarf-version 2 | FileCheck -check-prefixes=CHECK,ELF-ASM %s
+; RUN: llc -filetype=obj -O0 %s -mtriple=x86_64-linux-gnu -o %t-2 -dwarf-version 2
+; RUN: llvm-dwarfdump %t-2 | FileCheck %s -check-prefix=CHECK-DWARF
+; RUN: llc -filetype=obj -O0 %s -mtriple=x86_64-linux-gnu -o %t-4 -dwarf-version 2
+; RUN: llvm-dwarfdump %t-4 | FileCheck %s -check-prefix=CHECK-DWARF
 
-; RUN: llc -filetype=asm -O0 -mtriple=x86_64-apple-darwin < %s | FileCheck --check-prefix=DARWIN-ASM %s
-; RUN: llc -filetype=obj %s -mtriple=x86_64-apple-darwin -o %t2
-; RUN: llvm-dwarfdump %t2 | FileCheck %s -check-prefix=DARWIN-DWARF
+; RUN: llc -filetype=asm -O0 -mtriple=x86_64-apple-darwin < %s -dwarf-version 2 | FileCheck -check-prefixes=CHECK,DARWIN-ASM2 %s
+; RUN: llc -filetype=asm -O0 -mtriple=x86_64-apple-darwin < %s -dwarf-version 4 | FileCheck -check-prefixes=CHECK,DARWIN-ASM4 %s
+; RUN: llc -filetype=obj %s -mtriple=x86_64-apple-darwin -o %t2-2 -dwarf-version 2
+; RUN: llvm-dwarfdump %t2-2 | FileCheck %s -check-prefix=CHECK-DWARF
+; RUN: llc -filetype=obj %s -mtriple=x86_64-apple-darwin -o %t2-4 -dwarf-version 4
+; RUN: llvm-dwarfdump %t2-4 | FileCheck %s -check-prefix=CHECK-DWARF
+
+; RUN: llc -filetype=asm -O0 -mtriple=x86_64-pc-win32 < %s -dwarf-version 2 | FileCheck -check-prefixes=CHECK,COFF-ASM %s
+; RUN: llc -filetype=asm -O0 -mtriple=x86_64-pc-win32 < %s -dwarf-version 4 | FileCheck -check-prefixes=CHECK,COFF-ASM %s
+; RUN: llc -filetype=obj -O0 %s -mtriple=x86_64-pc-win32 -o %t3-2 -dwarf-version 2
+; RUN: llvm-dwarfdump %t3-2 | FileCheck %s -check-prefix=CHECK-DWARF2
+; RUN: llc -filetype=obj -O0 %s -mtriple=x86_64-pc-win32 -o %t3-4 -dwarf-version 4
+; RUN: llvm-dwarfdump %t3-4 | FileCheck %s -check-prefix=CHECK-DWARF
 
 ; Testing case generated from:
 ; clang++ tu1.cpp tu2.cpp -g -emit-llvm -c
 ; Make sure we use relocation for ref_addr on non-darwin platforms.
 ; CHECK: DW_TAG_compile_unit
 ; CHECK: DW_TAG_variable
-; CHECK: .long [[TYPE:.*]] # DW_AT_type
+; ELF-ASM: .long [[TYPE:.*]] # DW_AT_type
+; DARWIN-ASM2: .long [[TYPE:.*]] ## DW_AT_type
+; DARWIN-ASM4: .long [[TYPE:.*]] ## DW_AT_type
+; COFF-ASM: .long [[TYPE:.*]] # DW_AT_type
 ; CHECK: DW_TAG_structure_type
 ; CHECK: cu_begin1
 ; CHECK: DW_TAG_compile_unit
 ; This variable's type is in the 1st CU.
 ; CHECK: DW_TAG_variable
 ; Make sure this is relocatable.
-; CHECK: .quad .Lsection_info+[[TYPE]] # DW_AT_type
+; and test that we don't create the labels to emit a correct COFF relocation
+; ELF-ASM: .quad .Lsection_info+[[TYPE]] # DW_AT_type
+; COFF-ASM: .secrel32 .Lsection_info+[[TYPE]] # DW_AT_type
+; DARWIN-ASM2: .quad [[TYPE]] ## DW_AT_type
+; DARWIN-ASM4: .long [[TYPE]] ## DW_AT_type
 ; CHECK-NOT: DW_TAG_structure_type
 ; CHECK: .section
 
-; test that we don't create useless labels
-; DARWIN-ASM: .long [[TYPE:.*]] ## DW_AT_type
-; DARWIN-ASM: .quad [[TYPE]] ## DW_AT_type
-
 ; CHECK-DWARF: DW_TAG_compile_unit
 ; CHECK-DWARF: 0x[[ADDR:.*]]: DW_TAG_structure_type
 ; CHECK-DWARF: DW_TAG_compile_unit
 ; CHECK-DWARF: DW_TAG_variable
 ; CHECK-DWARF: DW_AT_type [DW_FORM_ref_addr] {{.*}}[[ADDR]])
 
-; DARWIN-DWARF: DW_TAG_compile_unit
-; DARWIN-DWARF: 0x[[ADDR:.*]]: DW_TAG_structure_type
-; DARWIN-DWARF: DW_TAG_compile_unit
-; DARWIN-DWARF: DW_TAG_variable
-; DARWIN-DWARF: DW_AT_type [DW_FORM_ref_addr] {{.*}}[[ADDR]])
+; CHECK-DWARF2: DW_TAG_compile_unit
+; CHECK-DWARF2: DW_TAG_variable
+; CHECK-DWARF2: DW_AT_type [DW_FORM_ref4] {{.*}} => {[[ADDR:.*]]})
+; CHECK-DWARF2: [[ADDR]]: DW_TAG_structure_type
 
 source_filename = "test/DebugInfo/X86/ref_addr_relocation.ll"