diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2015-06-21 13:59:01 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2015-06-21 13:59:01 +0000 |
| commit | 3a0822f094b578157263e04114075ad7df81db41 (patch) | |
| tree | bc48361fe2cd1ca5f93ac01b38b183774468fc79 /lib/CodeGen/AsmPrinter | |
| parent | 85d8b2bbe386bcfe669575d05b61482d7be07e5d (diff) | |
Notes
Diffstat (limited to 'lib/CodeGen/AsmPrinter')
24 files changed, 186 insertions, 138 deletions
diff --git a/lib/CodeGen/AsmPrinter/AddressPool.h b/lib/CodeGen/AsmPrinter/AddressPool.h index 211fc98c7f6f..e0ce3f90bc34 100644 --- a/lib/CodeGen/AsmPrinter/AddressPool.h +++ b/lib/CodeGen/AsmPrinter/AddressPool.h @@ -48,5 +48,5 @@ public: void resetUsedFlag() { HasBeenUsed = false; } }; -} +} // namespace llvm #endif diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 2e3b83a09520..95da5887658e 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -151,7 +151,7 @@ void AsmPrinter::EmitToStreamer(MCStreamer &S, const MCInst &Inst) { } StringRef AsmPrinter::getTargetTriple() const { - return TM.getTargetTriple(); + return TM.getTargetTriple().str(); } /// getCurrentSection() - Return the current section we are emitting to. @@ -172,7 +172,6 @@ void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const { bool AsmPrinter::doInitialization(Module &M) { MMI = getAnalysisIfAvailable<MachineModuleInfo>(); - MMI->AnalyzeModule(M); // Initialize TargetLoweringObjectFile. const_cast<TargetLoweringObjectFile&>(getObjFileLowering()) @@ -222,7 +221,8 @@ bool AsmPrinter::doInitialization(Module &M) { // We're at the module level. Construct MCSubtarget from the default CPU // and target triple. std::unique_ptr<MCSubtargetInfo> STI(TM.getTarget().createMCSubtargetInfo( - TM.getTargetTriple(), TM.getTargetCPU(), TM.getTargetFeatureString())); + TM.getTargetTriple().str(), TM.getTargetCPU(), + TM.getTargetFeatureString())); OutStreamer->AddComment("Start of file scope inline assembly"); OutStreamer->AddBlankLine(); EmitInlineAsm(M.getModuleInlineAsm()+"\n", *STI, TM.Options.MCOptions); @@ -232,7 +232,7 @@ bool AsmPrinter::doInitialization(Module &M) { if (MAI->doesSupportDebugInformation()) { bool skip_dwarf = false; - if (Triple(TM.getTargetTriple()).isKnownWindowsMSVCEnvironment()) { + if (TM.getTargetTriple().isKnownWindowsMSVCEnvironment()) { Handlers.push_back(HandlerInfo(new WinCodeViewLineTables(this), DbgTimerName, CodeViewLineTablesGroupName)); @@ -900,12 +900,11 @@ void AsmPrinter::EmitFunctionBody() { if (MAI->hasDotTypeDotSizeDirective()) { // We can get the size as difference between the function label and the // temp label. - const MCExpr *SizeExp = - MCBinaryExpr::createSub(MCSymbolRefExpr::create(CurrentFnEnd, OutContext), - MCSymbolRefExpr::create(CurrentFnSymForSize, - OutContext), - OutContext); - OutStreamer->emitELFSize(cast<MCSymbolELF>(CurrentFnSym), SizeExp); + const MCExpr *SizeExp = MCBinaryExpr::createSub( + MCSymbolRefExpr::create(CurrentFnEnd, OutContext), + MCSymbolRefExpr::create(CurrentFnSymForSize, OutContext), OutContext); + if (auto Sym = dyn_cast<MCSymbolELF>(CurrentFnSym)) + OutStreamer->emitELFSize(Sym, SizeExp); } for (const HandlerInfo &HI : Handlers) { @@ -1043,8 +1042,7 @@ bool AsmPrinter::doFinalization(Module &M) { if (!ModuleFlags.empty()) TLOF.emitModuleFlags(*OutStreamer, ModuleFlags, *Mang, TM); - Triple TT(TM.getTargetTriple()); - if (TT.isOSBinFormatELF()) { + if (TM.getTargetTriple().isOSBinFormatELF()) { MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>(); // Output stubs for external and common global variables. @@ -1591,25 +1589,7 @@ void AsmPrinter::EmitInt32(int Value) const { /// .set if it avoids relocations. void AsmPrinter::EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, unsigned Size) const { - if (!MAI->doesDwarfUseRelocationsAcrossSections()) - if (OutStreamer->emitAbsoluteSymbolDiff(Hi, Lo, Size)) - return; - - // Get the Hi-Lo expression. - const MCExpr *Diff = - MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, OutContext), - MCSymbolRefExpr::create(Lo, OutContext), - OutContext); - - if (!MAI->doesSetDirectiveSuppressesReloc()) { - OutStreamer->EmitValue(Diff, Size); - return; - } - - // Otherwise, emit with .set (aka assignment). - MCSymbol *SetLabel = createTempSymbol("set"); - OutStreamer->EmitAssignment(SetLabel, Diff); - OutStreamer->EmitSymbolValue(SetLabel, Size); + OutStreamer->emitAbsoluteSymbolDiff(Hi, Lo, Size); } /// EmitLabelPlusOffset - Emit something like ".long Label+Offset" @@ -1811,40 +1791,30 @@ static int isRepeatedByteSequence(const ConstantDataSequential *V) { /// composed of a repeated sequence of identical bytes and return the /// byte value. If it is not a repeated sequence, return -1. static int isRepeatedByteSequence(const Value *V, TargetMachine &TM) { - if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) { - if (CI->getBitWidth() > 64) return -1; - - uint64_t Size = - TM.getDataLayout()->getTypeAllocSize(V->getType()); - uint64_t Value = CI->getZExtValue(); - - // Make sure the constant is at least 8 bits long and has a power - // of 2 bit width. This guarantees the constant bit width is - // always a multiple of 8 bits, avoiding issues with padding out - // to Size and other such corner cases. - if (CI->getBitWidth() < 8 || !isPowerOf2_64(CI->getBitWidth())) return -1; + uint64_t Size = TM.getDataLayout()->getTypeAllocSizeInBits(V->getType()); + assert(Size % 8 == 0); - uint8_t Byte = static_cast<uint8_t>(Value); + // Extend the element to take zero padding into account. + APInt Value = CI->getValue().zextOrSelf(Size); + if (!Value.isSplat(8)) + return -1; - for (unsigned i = 1; i < Size; ++i) { - Value >>= 8; - if (static_cast<uint8_t>(Value) != Byte) return -1; - } - return Byte; + return Value.zextOrTrunc(8).getZExtValue(); } if (const ConstantArray *CA = dyn_cast<ConstantArray>(V)) { // Make sure all array elements are sequences of the same repeated // byte. assert(CA->getNumOperands() != 0 && "Should be a CAZ"); - int Byte = isRepeatedByteSequence(CA->getOperand(0), TM); - if (Byte == -1) return -1; + Constant *Op0 = CA->getOperand(0); + int Byte = isRepeatedByteSequence(Op0, TM); + if (Byte == -1) + return -1; - for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) { - int ThisByte = isRepeatedByteSequence(CA->getOperand(i), TM); - if (ThisByte == -1) return -1; - if (Byte != ThisByte) return -1; - } + // All array elements must be equal. + for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) + if (CA->getOperand(i) != Op0) + return -1; return Byte; } diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp index 7dbfddf60691..8ee613bcdb43 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp @@ -157,24 +157,20 @@ void AsmPrinter::EmitTTypeReference(const GlobalValue *GV, OutStreamer->EmitIntValue(0, GetSizeOfEncodedValue(Encoding)); } -/// EmitSectionOffset - Emit the 4-byte offset of Label from the start of its -/// section. This can be done with a special directive if the target supports -/// it (e.g. cygwin) or by emitting it as an offset from a label at the start -/// of the section. -/// -/// SectionLabel is a temporary label emitted at the start of the section that -/// Label lives in. -void AsmPrinter::emitSectionOffset(const MCSymbol *Label) const { - // On COFF targets, we have to emit the special .secrel32 directive. - if (MAI->needsDwarfSectionOffsetDirective()) { - OutStreamer->EmitCOFFSecRel32(Label); - return; - } +void AsmPrinter::emitDwarfSymbolReference(const MCSymbol *Label, + bool ForceOffset) const { + if (!ForceOffset) { + // On COFF targets, we have to emit the special .secrel32 directive. + if (MAI->needsDwarfSectionOffsetDirective()) { + OutStreamer->EmitCOFFSecRel32(Label); + return; + } - // If the format uses relocations with dwarf, refer to the symbol directly. - if (MAI->doesDwarfUseRelocationsAcrossSections()) { - OutStreamer->EmitSymbolValue(Label, 4); - return; + // If the format uses relocations with dwarf, refer to the symbol directly. + if (MAI->doesDwarfUseRelocationsAcrossSections()) { + OutStreamer->EmitSymbolValue(Label, 4); + return; + } } // Otherwise, emit it as a label difference from the start of the section. @@ -183,7 +179,7 @@ void AsmPrinter::emitSectionOffset(const MCSymbol *Label) const { void AsmPrinter::emitDwarfStringOffset(DwarfStringPoolEntryRef S) const { if (MAI->doesDwarfUseRelocationsAcrossSections()) { - emitSectionOffset(S.getSymbol()); + emitDwarfSymbolReference(S.getSymbol()); return; } diff --git a/lib/CodeGen/AsmPrinter/ByteStreamer.h b/lib/CodeGen/AsmPrinter/ByteStreamer.h index 0cc829fffc54..7a712a076dd9 100644 --- a/lib/CodeGen/AsmPrinter/ByteStreamer.h +++ b/lib/CodeGen/AsmPrinter/ByteStreamer.h @@ -103,6 +103,6 @@ public: } }; -} +} // namespace llvm #endif diff --git a/lib/CodeGen/AsmPrinter/DIE.cpp b/lib/CodeGen/AsmPrinter/DIE.cpp index fa8449e94c9f..4847de45789b 100644 --- a/lib/CodeGen/AsmPrinter/DIE.cpp +++ b/lib/CodeGen/AsmPrinter/DIE.cpp @@ -618,11 +618,7 @@ unsigned DIELocList::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { void DIELocList::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const { DwarfDebug *DD = AP->getDwarfDebug(); MCSymbol *Label = DD->getDebugLocs().getList(Index).Label; - - if (AP->MAI->doesDwarfUseRelocationsAcrossSections() && !DD->useSplitDwarf()) - AP->emitSectionOffset(Label); - else - AP->EmitLabelDifference(Label, Label->getSection().getBeginSymbol(), 4); + AP->emitDwarfSymbolReference(Label, /*ForceOffset*/ DD->useSplitDwarf()); } #ifndef NDEBUG diff --git a/lib/CodeGen/AsmPrinter/DIEHash.h b/lib/CodeGen/AsmPrinter/DIEHash.h index 1850e042f924..789e6dd91e01 100644 --- a/lib/CodeGen/AsmPrinter/DIEHash.h +++ b/lib/CodeGen/AsmPrinter/DIEHash.h @@ -157,6 +157,6 @@ private: AsmPrinter *AP; DenseMap<const DIE *, unsigned> Numbering; }; -} +} // namespace llvm #endif diff --git a/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h b/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h index 546d1b443781..5d4005018013 100644 --- a/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h +++ b/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h @@ -55,6 +55,6 @@ public: void calculateDbgValueHistory(const MachineFunction *MF, const TargetRegisterInfo *TRI, DbgValueHistoryMap &Result); -} +} // namespace llvm #endif diff --git a/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/lib/CodeGen/AsmPrinter/DebugLocEntry.h index 6a943c64ea22..083228b8fd41 100644 --- a/lib/CodeGen/AsmPrinter/DebugLocEntry.h +++ b/lib/CodeGen/AsmPrinter/DebugLocEntry.h @@ -175,6 +175,6 @@ inline bool operator<(const DebugLocEntry::Value &A, B.getExpression()->getBitPieceOffset(); } -} +} // namespace llvm #endif diff --git a/lib/CodeGen/AsmPrinter/DebugLocStream.h b/lib/CodeGen/AsmPrinter/DebugLocStream.h index 3001da21b907..1ae385db4a55 100644 --- a/lib/CodeGen/AsmPrinter/DebugLocStream.h +++ b/lib/CodeGen/AsmPrinter/DebugLocStream.h @@ -129,5 +129,5 @@ private: return Entries[EI + 1].CommentOffset - Entries[EI].CommentOffset; } }; -} +} // namespace llvm #endif diff --git a/lib/CodeGen/AsmPrinter/DwarfAccelTable.h b/lib/CodeGen/AsmPrinter/DwarfAccelTable.h index 4d81441f6a72..cc677c260071 100644 --- a/lib/CodeGen/AsmPrinter/DwarfAccelTable.h +++ b/lib/CodeGen/AsmPrinter/DwarfAccelTable.h @@ -252,5 +252,5 @@ public: void dump() { print(dbgs()); } #endif }; -} +} // namespace llvm #endif diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 689184a651ed..45c56fbb4463 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -817,4 +817,4 @@ bool DwarfCompileUnit::includeMinimalInlineScopes() const { return getCUNode()->getEmissionKind() == DIBuilder::LineTablesOnly || (DD->useSplitDwarf() && !Skeleton); } -} // end llvm namespace +} // namespace llvm diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h index 50e4a54eb3e0..48c302bf9c18 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -231,6 +231,6 @@ public: const MCSymbol *getBaseAddress() const { return BaseAddress; } }; -} // end llvm namespace +} // namespace llvm #endif diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 3f6665bd5768..fb3316985b86 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1414,7 +1414,7 @@ void DwarfDebug::emitDebugPubSection( Asm->EmitInt16(dwarf::DW_PUBNAMES_VERSION); Asm->OutStreamer->AddComment("Offset of Compilation Unit Info"); - Asm->emitSectionOffset(TheU->getLabelBegin()); + Asm->emitDwarfSymbolReference(TheU->getLabelBegin()); Asm->OutStreamer->AddComment("Compilation Unit Length"); Asm->EmitInt32(TheU->getLength()); @@ -1562,8 +1562,6 @@ void DwarfDebug::emitDebugLoc() { Asm->OutStreamer->EmitLabel(List.Label); const DwarfCompileUnit *CU = List.CU; for (const auto &Entry : DebugLocs.getEntries(List)) { - if (Entry.BeginSym == Entry.EndSym) - continue; // Set up the range. This range is relative to the entry point of the // compile unit. This is a hard coded 0 for low_pc when we're emitting // ranges, or the DW_AT_low_pc on the compile unit otherwise. @@ -1741,7 +1739,7 @@ void DwarfDebug::emitDebugARanges() { Asm->OutStreamer->AddComment("DWARF Arange version number"); Asm->EmitInt16(dwarf::DW_ARANGES_VERSION); Asm->OutStreamer->AddComment("Offset Into Debug Info Section"); - Asm->emitSectionOffset(CU->getLabelBegin()); + Asm->emitDwarfSymbolReference(CU->getLabelBegin()); Asm->OutStreamer->AddComment("Address Size (in bytes)"); Asm->EmitInt8(PtrSize); Asm->OutStreamer->AddComment("Segment Size (in bytes)"); diff --git a/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/lib/CodeGen/AsmPrinter/DwarfExpression.cpp index d56982712d53..a2799b8d6300 100644 --- a/lib/CodeGen/AsmPrinter/DwarfExpression.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfExpression.cpp @@ -65,11 +65,6 @@ void DwarfExpression::AddShr(unsigned ShiftBy) { EmitOp(dwarf::DW_OP_shr); } -void DwarfExpression::AddOpStackValue() { - if (DwarfVersion >= 4) - EmitOp(dwarf::DW_OP_stack_value); -} - bool DwarfExpression::AddMachineRegIndirect(unsigned MachineReg, int Offset) { if (isFrameRegister(MachineReg)) { // If variable offset is based in frame register then use fbreg. @@ -177,14 +172,16 @@ void DwarfExpression::AddSignedConstant(int Value) { // value, so the producers and consumers started to rely on heuristics // to disambiguate the value vs. location status of the expression. // See PR21176 for more details. - AddOpStackValue(); + if (DwarfVersion >= 4) + EmitOp(dwarf::DW_OP_stack_value); } void DwarfExpression::AddUnsignedConstant(unsigned Value) { EmitOp(dwarf::DW_OP_constu); EmitUnsigned(Value); // cf. comment in DwarfExpression::AddSignedConstant(). - AddOpStackValue(); + if (DwarfVersion >= 4) + EmitOp(dwarf::DW_OP_stack_value); } static unsigned getOffsetOrZero(unsigned OffsetInBits, @@ -215,30 +212,15 @@ bool DwarfExpression::AddMachineRegExpression(const DIExpression *Expr, getOffsetOrZero(OffsetInBits, PieceOffsetInBits)); } case dwarf::DW_OP_plus: { + // [DW_OP_reg,Offset,DW_OP_plus,DW_OP_deref] --> [DW_OP_breg,Offset]. auto N = I.getNext(); - unsigned Offset = I->getArg(0); - // First combine all DW_OP_plus until we hit either a DW_OP_deref or a - // DW_OP_bit_piece - while (N != E && N->getOp() == dwarf::DW_OP_plus) { - Offset += N->getArg(0); - ++I; - N = I.getNext(); - } if (N != E && N->getOp() == dwarf::DW_OP_deref) { - // [DW_OP_reg,Offset,DW_OP_plus,DW_OP_deref] --> [DW_OP_breg,Offset]. + unsigned Offset = I->getArg(0); ValidReg = AddMachineRegIndirect(MachineReg, Offset); std::advance(I, 2); - } else { - assert ((N == E) || (N->getOp() == dwarf::DW_OP_bit_piece)); - if (Offset == 0) { - ValidReg = AddMachineRegPiece(MachineReg); - } else { - ValidReg = AddMachineRegIndirect(MachineReg, Offset); - AddOpStackValue(); - } - ++I; - } - break; + break; + } else + ValidReg = AddMachineRegPiece(MachineReg); } case dwarf::DW_OP_deref: { // [DW_OP_reg,DW_OP_deref] --> [DW_OP_breg]. @@ -255,7 +237,6 @@ bool DwarfExpression::AddMachineRegExpression(const DIExpression *Expr, // Emit remaining elements of the expression. AddExpression(I, E, PieceOffsetInBits); - return true; } diff --git a/lib/CodeGen/AsmPrinter/DwarfExpression.h b/lib/CodeGen/AsmPrinter/DwarfExpression.h index f6249fff4253..154d7d9b9645 100644 --- a/lib/CodeGen/AsmPrinter/DwarfExpression.h +++ b/lib/CodeGen/AsmPrinter/DwarfExpression.h @@ -83,9 +83,6 @@ public: bool AddMachineRegPiece(unsigned MachineReg, unsigned PieceSizeInBits = 0, unsigned PieceOffsetInBits = 0); - /// Emit a DW_OP_stack_value - void AddOpStackValue(); - /// Emit a signed constant. void AddSignedConstant(int Value); /// Emit an unsigned constant. @@ -134,6 +131,6 @@ public: void EmitUnsigned(uint64_t Value) override; bool isFrameRegister(unsigned MachineReg) override; }; -} +} // namespace llvm #endif diff --git a/lib/CodeGen/AsmPrinter/DwarfFile.cpp b/lib/CodeGen/AsmPrinter/DwarfFile.cpp index 5ef333c4cf44..fdefb1df84b6 100644 --- a/lib/CodeGen/AsmPrinter/DwarfFile.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfFile.cpp @@ -170,4 +170,4 @@ bool DwarfFile::addScopeVariable(LexicalScope *LS, DbgVariable *Var) { Vars.push_back(Var); return true; } -} +} // namespace llvm diff --git a/lib/CodeGen/AsmPrinter/DwarfFile.h b/lib/CodeGen/AsmPrinter/DwarfFile.h index 8402027edd6f..22759fdecccf 100644 --- a/lib/CodeGen/AsmPrinter/DwarfFile.h +++ b/lib/CodeGen/AsmPrinter/DwarfFile.h @@ -114,5 +114,5 @@ public: return DITypeNodeToDieMap.lookup(TypeMD); } }; -} +} // namespace llvm #endif diff --git a/lib/CodeGen/AsmPrinter/DwarfStringPool.h b/lib/CodeGen/AsmPrinter/DwarfStringPool.h index 93a168485a54..c10725815351 100644 --- a/lib/CodeGen/AsmPrinter/DwarfStringPool.h +++ b/lib/CodeGen/AsmPrinter/DwarfStringPool.h @@ -45,5 +45,5 @@ public: /// Get a reference to an entry in the string pool. EntryRef getEntry(AsmPrinter &Asm, StringRef Str); }; -} +} // namespace llvm #endif diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index 907f6706bc6a..f4b15ba053e9 100644 --- a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -931,7 +931,7 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) { StringRef PropertyName = Property->getName(); addString(ElemDie, dwarf::DW_AT_APPLE_property_name, PropertyName); if (Property->getType()) - addType(ElemDie, Property->getType()); + addType(ElemDie, resolve(Property->getType())); addSourceLine(ElemDie, Property); StringRef GetterName = Property->getGetterName(); if (!GetterName.empty()) @@ -1449,10 +1449,8 @@ void DwarfUnit::emitHeader(bool UseOffsets) { // start of the section. Use a relocatable offset where needed to ensure // linking doesn't invalidate that offset. const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); - if (!UseOffsets) - Asm->emitSectionOffset(TLOF.getDwarfAbbrevSection()->getBeginSymbol()); - else - Asm->EmitInt32(0); + Asm->emitDwarfSymbolReference(TLOF.getDwarfAbbrevSection()->getBeginSymbol(), + UseOffsets); Asm->OutStreamer->AddComment("Address Size (in bytes)"); Asm->EmitInt8(Asm->getDataLayout().getPointerSize()); diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.h b/lib/CodeGen/AsmPrinter/DwarfUnit.h index f56c9b4eb13e..200ddf0f3cbe 100644 --- a/lib/CodeGen/AsmPrinter/DwarfUnit.h +++ b/lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -402,5 +402,5 @@ public: } DwarfCompileUnit &getCU() override { return CU; } }; -} // end llvm namespace +} // namespace llvm #endif diff --git a/lib/CodeGen/AsmPrinter/EHStreamer.h b/lib/CodeGen/AsmPrinter/EHStreamer.h index 65973fab6b21..128a8ad39255 100644 --- a/lib/CodeGen/AsmPrinter/EHStreamer.h +++ b/lib/CodeGen/AsmPrinter/EHStreamer.h @@ -132,7 +132,7 @@ public: void beginInstruction(const MachineInstr *MI) override {} void endInstruction() override {} }; -} +} // namespace llvm #endif diff --git a/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp b/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp index 535b1f605853..11bfe767a27b 100644 --- a/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp +++ b/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp @@ -378,4 +378,4 @@ void WinCodeViewLineTables::beginInstruction(const MachineInstr *MI) { return; maybeRecordLocation(DL, Asm->MF); } -} +} // namespace llvm diff --git a/lib/CodeGen/AsmPrinter/WinException.cpp b/lib/CodeGen/AsmPrinter/WinException.cpp index f1663503c08e..1ba6060a89f6 100644 --- a/lib/CodeGen/AsmPrinter/WinException.cpp +++ b/lib/CodeGen/AsmPrinter/WinException.cpp @@ -50,6 +50,11 @@ WinException::~WinException() {} /// endModule - Emit all exception information that should come after the /// content. void WinException::endModule() { + auto &OS = *Asm->OutStreamer; + const Module *M = MMI->getModule(); + for (const Function &F : *M) + if (F.hasFnAttribute("safeseh")) + OS.EmitCOFFSafeSEH(Asm->getSymbol(&F)); } void WinException::beginFunction(const MachineFunction *MF) { @@ -144,7 +149,7 @@ void WinException::endFunction(const MachineFunction *MF) { if (Per == EHPersonality::MSVC_Win64SEH) emitCSpecificHandlerTable(); else if (Per == EHPersonality::MSVC_X86SEH) - emitCSpecificHandlerTable(); // FIXME + emitExceptHandlerTable(MF); else if (Per == EHPersonality::MSVC_CXX) emitCXXFrameHandler3Table(MF); else @@ -444,7 +449,7 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) { Asm->OutContext.getOrCreateParentFrameOffsetSymbol( GlobalValue::getRealLinkageName(HT.Handler->getName())); const MCSymbolRefExpr *ParentFrameOffsetRef = MCSymbolRefExpr::create( - ParentFrameOffset, MCSymbolRefExpr::VK_None, Asm->OutContext); + ParentFrameOffset, Asm->OutContext); OS.EmitValue(ParentFrameOffsetRef, 4); // ParentFrameOffset } } @@ -541,3 +546,103 @@ void WinException::extendIP2StateTable(const MachineFunction *MF, } } } + +/// Emit the language-specific data that _except_handler3 and 4 expect. This is +/// functionally equivalent to the __C_specific_handler table, except it is +/// indexed by state number instead of IP. +void WinException::emitExceptHandlerTable(const MachineFunction *MF) { + MCStreamer &OS = *Asm->OutStreamer; + + // Define the EH registration node offset label in terms of its frameescape + // label. The WinEHStatePass ensures that the registration node is passed to + // frameescape. This allows SEH filter functions to access the + // EXCEPTION_POINTERS field, which is filled in by the _except_handlerN. + const Function *F = MF->getFunction(); + WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(F); + assert(FuncInfo.EHRegNodeEscapeIndex != INT_MAX && + "no EH reg node frameescape index"); + StringRef FLinkageName = GlobalValue::getRealLinkageName(F->getName()); + MCSymbol *ParentFrameOffset = + Asm->OutContext.getOrCreateParentFrameOffsetSymbol(FLinkageName); + MCSymbol *FrameAllocSym = Asm->OutContext.getOrCreateFrameAllocSymbol( + FLinkageName, FuncInfo.EHRegNodeEscapeIndex); + const MCSymbolRefExpr *FrameAllocSymRef = + MCSymbolRefExpr::create(FrameAllocSym, Asm->OutContext); + OS.EmitAssignment(ParentFrameOffset, FrameAllocSymRef); + + // Emit the __ehtable label that we use for llvm.x86.seh.lsda. + MCSymbol *LSDALabel = Asm->OutContext.getOrCreateLSDASymbol(FLinkageName); + OS.EmitLabel(LSDALabel); + + const Function *Per = MMI->getPersonality(); + StringRef PerName = Per->getName(); + int BaseState = -1; + if (PerName == "_except_handler4") { + // The LSDA for _except_handler4 starts with this struct, followed by the + // scope table: + // + // struct EH4ScopeTable { + // int32_t GSCookieOffset; + // int32_t GSCookieXOROffset; + // int32_t EHCookieOffset; + // int32_t EHCookieXOROffset; + // ScopeTableEntry ScopeRecord[]; + // }; + // + // Only the EHCookieOffset field appears to vary, and it appears to be the + // offset from the final saved SP value to the retaddr. + OS.EmitIntValue(-2, 4); + OS.EmitIntValue(0, 4); + // FIXME: Calculate. + OS.EmitIntValue(9999, 4); + OS.EmitIntValue(0, 4); + BaseState = -2; + } + + // Build a list of pointers to LandingPadInfos and then sort by WinEHState. + const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads(); + SmallVector<const LandingPadInfo *, 4> LPads; + LPads.reserve((PadInfos.size())); + for (const LandingPadInfo &LPInfo : PadInfos) + LPads.push_back(&LPInfo); + std::sort(LPads.begin(), LPads.end(), + [](const LandingPadInfo *L, const LandingPadInfo *R) { + return L->WinEHState < R->WinEHState; + }); + + // For each action in each lpad, emit one of these: + // struct ScopeTableEntry { + // int32_t EnclosingLevel; + // int32_t (__cdecl *Filter)(); + // void *HandlerOrFinally; + // }; + // + // The "outermost" action will use BaseState as its enclosing level. Each + // other action will refer to the previous state as its enclosing level. + int CurState = 0; + for (const LandingPadInfo *LPInfo : LPads) { + int EnclosingLevel = BaseState; + assert(CurState + int(LPInfo->SEHHandlers.size()) - 1 == + LPInfo->WinEHState && + "gaps in the SEH scope table"); + for (auto I = LPInfo->SEHHandlers.rbegin(), E = LPInfo->SEHHandlers.rend(); + I != E; ++I) { + const SEHHandler &Handler = *I; + const BlockAddress *BA = Handler.RecoverBA; + const Function *F = Handler.FilterOrFinally; + assert(F && "cannot catch all in 32-bit SEH without filter function"); + const MCExpr *FilterOrNull = + create32bitRef(BA ? Asm->getSymbol(F) : nullptr); + const MCExpr *ExceptOrFinally = create32bitRef( + BA ? Asm->GetBlockAddressSymbol(BA) : Asm->getSymbol(F)); + + OS.EmitIntValue(EnclosingLevel, 4); + OS.EmitValue(FilterOrNull, 4); + OS.EmitValue(ExceptOrFinally, 4); + + // The next state unwinds to this state. + EnclosingLevel = CurState; + CurState++; + } + } +} diff --git a/lib/CodeGen/AsmPrinter/WinException.h b/lib/CodeGen/AsmPrinter/WinException.h index 478899b79da9..bbff3c24cffc 100644 --- a/lib/CodeGen/AsmPrinter/WinException.h +++ b/lib/CodeGen/AsmPrinter/WinException.h @@ -38,8 +38,15 @@ class WinException : public EHStreamer { void emitCSpecificHandlerTable(); + /// Emit the EH table data for 32-bit and 64-bit functions using + /// the __CxxFrameHandler3 personality. void emitCXXFrameHandler3Table(const MachineFunction *MF); + /// Emit the EH table data for _except_handler3 and _except_handler4 + /// personality functions. These are only used on 32-bit and do not use CFI + /// tables. + void emitExceptHandlerTable(const MachineFunction *MF); + void extendIP2StateTable(const MachineFunction *MF, const Function *ParentF, WinEHFuncInfo &FuncInfo); @@ -63,7 +70,7 @@ public: /// Gather and emit post-function exception information. void endFunction(const MachineFunction *) override; }; -} +} // namespace llvm #endif |
