Skip to content

Commit

Permalink
Reapply "[CodeGen] Fix invalid DWARF info on Win64"
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Keno committed Jan 2, 2017
1 parent 5b08d83 commit e345a27
Show file tree
Hide file tree
Showing 13 changed files with 76 additions and 36 deletions.
2 changes: 1 addition & 1 deletion docs/Extensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
...
Expand Down
2 changes: 1 addition & 1 deletion include/llvm/MC/MCStreamer.h
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ class MCStreamer {
/// \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.
///
Expand Down
2 changes: 1 addition & 1 deletion include/llvm/MC/MCWinCOFFStreamer.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class MCWinCOFFStreamer : public MCObjectStreamer {
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,
Expand Down
4 changes: 3 additions & 1 deletion lib/CodeGen/AsmPrinter/AsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
4 changes: 2 additions & 2 deletions lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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");
Expand Down
5 changes: 3 additions & 2 deletions lib/CodeGen/AsmPrinter/DIE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
}
}
Expand Down
6 changes: 4 additions & 2 deletions lib/MC/MCAsmStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ class MCAsmStreamer final : public MCStreamer {
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;
Expand Down Expand Up @@ -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();
}

Expand Down
2 changes: 1 addition & 1 deletion lib/MC/MCCodeView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
15 changes: 14 additions & 1 deletion lib/MC/MCParser/COFFAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
5 changes: 2 additions & 3 deletions lib/MC/MCStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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
Expand Down
15 changes: 12 additions & 3 deletions lib/MC/WinCOFFStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
48 changes: 31 additions & 17 deletions test/DebugInfo/X86/ref_addr_relocation.ll
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -22,33 +34,35 @@
; 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
; CHECK-NOT: DW_TAG_structure_type
; 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"

Expand Down

0 comments on commit e345a27

Please sign in to comment.