diff options
Diffstat (limited to 'lib/MC/WinCOFFStreamer.cpp')
-rw-r--r-- | lib/MC/WinCOFFStreamer.cpp | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/lib/MC/WinCOFFStreamer.cpp b/lib/MC/WinCOFFStreamer.cpp index d391a3f..6a8054d 100644 --- a/lib/MC/WinCOFFStreamer.cpp +++ b/lib/MC/WinCOFFStreamer.cpp @@ -25,11 +25,11 @@ #include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCValue.h" -#include "llvm/MC/MCWin64EH.h" #include "llvm/MC/MCWinCOFFStreamer.h" #include "llvm/Support/COFF.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" @@ -61,7 +61,7 @@ void MCWinCOFFStreamer::EmitInstToData(const MCInst &Inst, DF->getContents().append(Code.begin(), Code.end()); } -void MCWinCOFFStreamer::InitSections() { +void MCWinCOFFStreamer::InitSections(bool NoExecStack) { // FIXME: this is identical to the ELF one. // This emulates the same behavior of GNU as. This makes it easier // to compare the output as the major sections are in the same order. @@ -133,7 +133,7 @@ void MCWinCOFFStreamer::EmitCOFFSymbolStorageClass(int StorageClass) { if (!CurSymbol) FatalError("storage class specified outside of symbol definition"); - if (StorageClass & ~0xff) + if (StorageClass & ~COFF::SSC_Invalid) FatalError(Twine("storage class value '") + itostr(StorageClass) + "' out of range"); @@ -163,7 +163,7 @@ void MCWinCOFFStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) { const MCSymbolRefExpr *SRE = MCSymbolRefExpr::Create(Symbol, getContext()); MCFixup Fixup = MCFixup::Create(DF->getContents().size(), SRE, FK_SecRel_2); DF->getFixups().push_back(Fixup); - DF->getContents().resize(DF->getContents().size() + 4, 0); + DF->getContents().resize(DF->getContents().size() + 2, 0); } void MCWinCOFFStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) { @@ -184,14 +184,35 @@ void MCWinCOFFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, Symbol->getSection().getVariant() == MCSection::SV_COFF) && "Got non-COFF section in the COFF backend!"); - if (ByteAlignment > 32) - report_fatal_error("alignment is limited to 32-bytes"); + const Triple &T = getContext().getObjectFileInfo()->getTargetTriple(); + if (T.isKnownWindowsMSVCEnvironment()) { + if (ByteAlignment > 32) + report_fatal_error("alignment is limited to 32-bytes"); + + // Round size up to alignment so that we will honor the alignment request. + Size = std::max(Size, static_cast<uint64_t>(ByteAlignment)); + } AssignSection(Symbol, nullptr); MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); SD.setExternal(true); SD.setCommon(Size, ByteAlignment); + + if (!T.isKnownWindowsMSVCEnvironment() && ByteAlignment > 1) { + SmallString<128> Directive; + raw_svector_ostream OS(Directive); + const MCObjectFileInfo *MFI = getContext().getObjectFileInfo(); + + OS << " -aligncomm:\"" << Symbol->getName() << "\"," + << Log2_32_Ceil(ByteAlignment); + OS.flush(); + + PushSection(); + SwitchSection(MFI->getDrectveSection()); + EmitBytes(Directive); + PopSection(); + } } void MCWinCOFFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, |