diff options
author | David Majnemer <david.majnemer@gmail.com> | 2015-05-30 04:56:02 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2015-05-30 04:56:02 +0000 |
commit | 4eecd30d1910ba784e98a7d628f0e2448712725f (patch) | |
tree | 94b5f2352aff7eb8f73b7966f22cedc561f4abf3 /llvm/lib/MC/WinCOFFObjectWriter.cpp | |
parent | 9cc2516676063f190e04e231284a52cb45fdb273 (diff) | |
download | llvm-4eecd30d1910ba784e98a7d628f0e2448712725f.zip llvm-4eecd30d1910ba784e98a7d628f0e2448712725f.tar.gz llvm-4eecd30d1910ba784e98a7d628f0e2448712725f.tar.bz2 |
[WinCOFF] Add support for the .safeseh directive
.safeseh adds an entry to the .sxdata section to register all the
appropriate functions which may handle an exception. This entry is not
a relocation to the symbol but instead the symbol table index of the
function.
llvm-svn: 238641
Diffstat (limited to 'llvm/lib/MC/WinCOFFObjectWriter.cpp')
-rw-r--r-- | llvm/lib/MC/WinCOFFObjectWriter.cpp | 44 |
1 files changed, 27 insertions, 17 deletions
diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp index ddec16c..2f6d180 100644 --- a/llvm/lib/MC/WinCOFFObjectWriter.cpp +++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp @@ -21,6 +21,7 @@ #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" @@ -76,6 +77,13 @@ public: 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. @@ -219,6 +227,10 @@ bool COFFSymbol::should_keep() const { 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; @@ -416,11 +428,13 @@ void WinCOFFObjectWriter::DefineSymbol(const MCSymbol &Symbol, 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()); @@ -828,13 +842,9 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, 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; @@ -877,12 +887,13 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, 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. @@ -904,11 +915,11 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, // 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(); } } @@ -934,8 +945,7 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, 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. @@ -984,8 +994,8 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, 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(); } } @@ -1067,7 +1077,7 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, "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()); |