FT_Org,
FT_Dwarf,
FT_DwarfFrame,
- FT_LEB
+ FT_LEB,
+ FT_SafeSEH
};
private:
}
};
+class MCSafeSEHFragment : public MCFragment {
+ virtual void anchor();
+
+ const MCSymbol *Sym;
+
+public:
+ MCSafeSEHFragment(const MCSymbol *Sym, MCSection *Sec = nullptr)
+ : MCFragment(FT_SafeSEH, Sec), Sym(Sym) {}
+
+ /// \name Accessors
+ /// @{
+
+ const MCSymbol *getSymbol() { return Sym; }
+ const MCSymbol *getSymbol() const { return Sym; }
+
+ /// @}
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_SafeSEH;
+ }
+};
+
// FIXME: This really doesn't belong here. See comments below.
struct IndirectSymbolData {
MCSymbol *Symbol;
MCSection *DrectveSection;
MCSection *PDataSection;
MCSection *XDataSection;
+ MCSection *SXDataSection;
public:
void InitMCObjectFileInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM,
MCSection *getDrectveSection() const { return DrectveSection; }
MCSection *getPDataSection() const { return PDataSection; }
MCSection *getXDataSection() const { return XDataSection; }
+ MCSection *getSXDataSection() const { return SXDataSection; }
MCSection *getEHFrameSection() {
if (!EHFrameSection)
/// \brief Marks the end of the symbol definition.
virtual void EndCOFFSymbolDef();
+ virtual void EmitCOFFSafeSEH(MCSymbol const *Symbol);
+
/// \brief Emits a COFF section index.
///
/// \param Symbol - Symbol the section number relocation should point to.
void EmitCOFFSymbolStorageClass(int StorageClass) override;
void EmitCOFFSymbolType(int Type) override;
void EndCOFFSymbolDef() override;
+ void EmitCOFFSafeSEH(MCSymbol const *Symbol) override;
void EmitCOFFSectionIndex(MCSymbol const *Symbol) override;
void EmitCOFFSecRel32(MCSymbol const *Symbol) override;
void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
SF_ClassMask = 0x00FF0000,
SF_ClassShift = 16,
- SF_WeakExternal = 0x01000000
+ SF_WeakExternal = 0x01000000,
+ SF_SafeSEH = 0x02000000,
};
enum SymbolSectionNumber : int32_t {
void EmitCOFFSymbolStorageClass(int StorageClass) override;
void EmitCOFFSymbolType(int Type) override;
void EndCOFFSymbolDef() override;
+ void EmitCOFFSafeSEH(MCSymbol const *Symbol) override;
void EmitCOFFSectionIndex(MCSymbol const *Symbol) override;
void EmitCOFFSecRel32(MCSymbol const *Symbol) override;
void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
EmitEOL();
}
+void MCAsmStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) {
+ OS << "\t.safeseh\t" << *Symbol;
+ EmitEOL();
+}
+
void MCAsmStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {
OS << "\t.secidx\t" << *Symbol;
EmitEOL();
case MCFragment::FT_LEB:
return cast<MCLEBFragment>(F).getContents().size();
+ case MCFragment::FT_SafeSEH:
+ return 4;
+
case MCFragment::FT_Align: {
const MCAlignFragment &AF = cast<MCAlignFragment>(F);
unsigned Offset = Layout.getFragmentOffset(&AF);
break;
}
+ case MCFragment::FT_SafeSEH: {
+ const MCSafeSEHFragment &SF = cast<MCSafeSEHFragment>(F);
+ OW->Write32(SF.getSymbol()->getIndex());
+ break;
+ }
+
case MCFragment::FT_Org: {
++stats::EmittedOrgFragments;
const MCOrgFragment &OF = cast<MCOrgFragment>(F);
case MCFragment::FT_Dwarf: OS << "MCDwarfFragment"; break;
case MCFragment::FT_DwarfFrame: OS << "MCDwarfCallFrameFragment"; break;
case MCFragment::FT_LEB: OS << "MCLEBFragment"; break;
+ case MCFragment::FT_SafeSEH: OS << "MCSafeSEHFragment"; break;
}
OS << "<MCFragment " << (void*) this << " LayoutOrder:" << LayoutOrder
OS << " Value:" << LF->getValue() << " Signed:" << LF->isSigned();
break;
}
+ case MCFragment::FT_SafeSEH: {
+ const MCSafeSEHFragment *F = cast<MCSafeSEHFragment>(this);
+ OS << "\n ";
+ OS << " Sym:";
+ F->getSymbol()->print(OS);
+ break;
+ }
}
OS << ">";
}
void MCFillFragment::anchor() { }
void MCOrgFragment::anchor() { }
void MCLEBFragment::anchor() { }
+void MCSafeSEHFragment::anchor() { }
void MCDwarfLineAddrFragment::anchor() { }
void MCDwarfCallFrameFragment::anchor() { }
".xdata", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ,
SectionKind::getDataRel());
+ SXDataSection = Ctx->getCOFFSection(".sxdata", COFF::IMAGE_SCN_LNK_INFO,
+ SectionKind::getMetadata());
+
TLSDataSection = Ctx->getCOFFSection(
".tls$", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ |
COFF::IMAGE_SCN_MEM_WRITE,
addDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef");
addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecRel32>(".secrel32");
addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecIdx>(".secidx");
+ addDirectiveHandler<&COFFAsmParser::ParseDirectiveSafeSEH>(".safeseh");
addDirectiveHandler<&COFFAsmParser::ParseDirectiveLinkOnce>(".linkonce");
// Win64 EH directives.
bool ParseDirectiveEndef(StringRef, SMLoc);
bool ParseDirectiveSecRel32(StringRef, SMLoc);
bool ParseDirectiveSecIdx(StringRef, SMLoc);
+ bool ParseDirectiveSafeSEH(StringRef, SMLoc);
bool parseCOMDATType(COFF::COMDATType &Type);
bool ParseDirectiveLinkOnce(StringRef, SMLoc);
return false;
}
+bool COFFAsmParser::ParseDirectiveSafeSEH(StringRef, SMLoc) {
+ StringRef SymbolID;
+ if (getParser().parseIdentifier(SymbolID))
+ return TokError("expected identifier in directive");
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in directive");
+
+ MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
+
+ Lex();
+ getStreamer().EmitCOFFSafeSEH(Symbol);
+ return false;
+}
+
bool COFFAsmParser::ParseDirectiveSecIdx(StringRef, SMLoc) {
StringRef SymbolID;
if (getParser().parseIdentifier(SymbolID))
CurrentWinFrameInfo->PrologEnd = Label;
}
+void MCStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) {
+}
+
void MCStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {
}
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSectionCOFF.h"
void set_name_offset(uint32_t Offset);
bool should_keep() const;
+
+ int64_t getIndex() const { return Index; }
+ void setIndex(int Value) {
+ Index = Value;
+ if (MC)
+ MC->setIndex(static_cast<uint32_t>(Value));
+ }
};
// This class contains staging data for a COFF relocation entry.
return true;
}
+ // if this is a safeseh handler, keep it
+ if (MC && (MC->getFlags() & COFF::SF_SafeSEH))
+ return true;
+
// if the section its in is being droped, drop it
if (Section->Number == -1)
return false;
const MCSymbol *Base = Layout.getBaseSymbol(Symbol);
coff_symbol->Data.Value = getSymbolValue(Symbol, Layout);
- coff_symbol->Data.Type = (Symbol.getFlags() & 0x0000FFFF) >> 0;
- coff_symbol->Data.StorageClass = (Symbol.getFlags() & 0x00FF0000) >> 16;
+ coff_symbol->Data.Type =
+ (Symbol.getFlags() & COFF::SF_TypeMask) >> COFF::SF_TypeShift;
+ coff_symbol->Data.StorageClass =
+ (Symbol.getFlags() & COFF::SF_ClassMask) >> COFF::SF_ClassShift;
// If no storage class was specified in the streamer, define it here.
- if (coff_symbol->Data.StorageClass == 0) {
+ if (coff_symbol->Data.StorageClass == COFF::IMAGE_SYM_CLASS_NULL) {
bool IsExternal = Symbol.isExternal() ||
(!Symbol.getFragment() && !Symbol.isVariable());
UseBigObj = NumberOfSections > COFF::MaxNumberOfSections16;
- DenseMap<COFFSection *, int32_t> SectionIndices(
- NextPowerOf2(NumberOfSections));
-
// Assign section numbers.
size_t Number = 1;
for (const auto &Section : Sections) {
- SectionIndices[Section.get()] = Number;
Section->Number = Number;
Section->Symbol->Data.SectionNumber = Number;
Section->Symbol->Aux[0].Aux.SectionDefinition.Number = Number;
if (Symbol->Section)
Symbol->Data.SectionNumber = Symbol->Section->Number;
if (Symbol->should_keep()) {
- Symbol->Index = Header.NumberOfSymbols++;
+ Symbol->setIndex(Header.NumberOfSymbols++);
// Update auxiliary symbol info.
Symbol->Data.NumberOfAuxSymbols = Symbol->Aux.size();
Header.NumberOfSymbols += Symbol->Data.NumberOfAuxSymbols;
- } else
- Symbol->Index = -1;
+ } else {
+ Symbol->setIndex(-1);
+ }
}
// Build string table.
// Fixup weak external references.
for (auto &Symbol : Symbols) {
if (Symbol->Other) {
- assert(Symbol->Index != -1);
+ assert(Symbol->getIndex() != -1);
assert(Symbol->Aux.size() == 1 && "Symbol must contain one aux symbol!");
assert(Symbol->Aux[0].AuxType == ATWeakExternal &&
"Symbol's aux symbol must be a Weak External!");
- Symbol->Aux[0].Aux.WeakExternal.TagIndex = Symbol->Other->Index;
+ Symbol->Aux[0].Aux.WeakExternal.TagIndex = Symbol->Other->getIndex();
}
}
if (Assoc->Number == -1)
continue;
- Section->Symbol->Aux[0].Aux.SectionDefinition.Number =
- SectionIndices[Assoc];
+ Section->Symbol->Aux[0].Aux.SectionDefinition.Number = Assoc->Number;
}
// Assign file offsets to COFF object file structures.
offset += COFF::RelocationSize * Sec->Relocations.size();
for (auto &Relocation : Sec->Relocations) {
- assert(Relocation.Symb->Index != -1);
- Relocation.Data.SymbolTableIndex = Relocation.Symb->Index;
+ assert(Relocation.Symb->getIndex() != -1);
+ Relocation.Data.SymbolTableIndex = Relocation.Symb->getIndex();
}
}
"Header::PointerToSymbolTable is insane!");
for (auto &Symbol : Symbols)
- if (Symbol->Index != -1)
+ if (Symbol->getIndex() != -1)
WriteSymbol(*Symbol);
OS.write(Strings.data().data(), Strings.data().size());
CurSymbol = nullptr;
}
+void MCWinCOFFStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) {
+ if (Symbol->getFlags() & COFF::SF_SafeSEH)
+ return;
+
+ MCSection *SXData = getContext().getObjectFileInfo()->getSXDataSection();
+ getAssembler().registerSection(*SXData);
+ if (SXData->getAlignment() < 4)
+ SXData->setAlignment(4);
+
+ new MCSafeSEHFragment(Symbol, SXData);
+
+ getAssembler().registerSymbol(*Symbol);
+ Symbol->modifyFlags(COFF::SF_SafeSEH, COFF::SF_SafeSEH);
+}
+
void MCWinCOFFStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {
MCDataFragment *DF = getOrCreateDataFragment();
const MCSymbolRefExpr *SRE = MCSymbolRefExpr::create(Symbol, getContext());