diff options
author | Keno Fischer <kfischer@college.harvard.edu> | 2016-12-08 01:40:21 +0000 |
---|---|---|
committer | Keno Fischer <kfischer@college.harvard.edu> | 2016-12-08 01:40:21 +0000 |
commit | 460218fb7d13132e4ea3def3b75eb43aa505b2db (patch) | |
tree | 0527e1c2d2e68010380ffda91cbb5c08bd3d8231 /llvm/lib | |
parent | 4574a890511d8bf7b9e7e3d59d9ad368ab79f843 (diff) | |
download | bcm5719-llvm-460218fb7d13132e4ea3def3b75eb43aa505b2db.tar.gz bcm5719-llvm-460218fb7d13132e4ea3def3b75eb43aa505b2db.zip |
[CodeGen] Fix invalid DWARF info on Win64
The relocations for `DIEEntry::EmitValue` were wrong for Win64
(emitting FK_Data_4 instead of FK_SecRel_4). This corrects that
oversight so that the DWARF data is correct in Win64 COFF files.
Fixes PR15393.
Patch by Jameson Nash <jameson@juliacomputing.com> based on a patch
by David Majnemer.
Differential Revision: https://reviews.llvm.org/D21731
llvm-svn: 289013
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DIE.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/MC/MCAsmStreamer.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/MC/MCCodeView.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/MC/MCParser/COFFAsmParser.cpp | 15 | ||||
-rw-r--r-- | llvm/lib/MC/MCStreamer.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/MC/WinCOFFStreamer.cpp | 15 |
9 files changed, 38 insertions, 15 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index b43d73988f4..9eba56d808d 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1688,7 +1688,7 @@ 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); return; } diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp index c104c3cd948..0358a2554c8 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp @@ -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; } diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index 8e170323e5e..23526f36f2e 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -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"); @@ -2271,7 +2271,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"); diff --git a/llvm/lib/CodeGen/AsmPrinter/DIE.cpp b/llvm/lib/CodeGen/AsmPrinter/DIE.cpp index 3fbb52f1380..a328851410f 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DIE.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DIE.cpp @@ -642,7 +642,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; } } diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index e36903e1fae..7cff7b9b272 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -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; @@ -614,9 +614,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(); } diff --git a/llvm/lib/MC/MCCodeView.cpp b/llvm/lib/MC/MCCodeView.cpp index ac1acc08b0c..ae0e50a37d7 100644 --- a/llvm/lib/MC/MCCodeView.cpp +++ b/llvm/lib/MC/MCCodeView.cpp @@ -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. diff --git a/llvm/lib/MC/MCParser/COFFAsmParser.cpp b/llvm/lib/MC/MCParser/COFFAsmParser.cpp index 2c9f9eb0cda..f4114795a92 100644 --- a/llvm/lib/MC/MCParser/COFFAsmParser.cpp +++ b/llvm/lib/MC/MCParser/COFFAsmParser.cpp @@ -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; } diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp index ebbf8116fa3..96fb566aa3a 100644 --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -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 diff --git a/llvm/lib/MC/WinCOFFStreamer.cpp b/llvm/lib/MC/WinCOFFStreamer.cpp index 5c6407ef1e5..6383d879403 100644 --- a/llvm/lib/MC/WinCOFFStreamer.cpp +++ b/llvm/lib/MC/WinCOFFStreamer.cpp @@ -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); } |