diff options
Diffstat (limited to 'llvm/lib/MC/MCXCOFFStreamer.cpp')
-rw-r--r-- | llvm/lib/MC/MCXCOFFStreamer.cpp | 62 |
1 files changed, 51 insertions, 11 deletions
diff --git a/llvm/lib/MC/MCXCOFFStreamer.cpp b/llvm/lib/MC/MCXCOFFStreamer.cpp index 6efa167ced42..ec9e89fac416 100644 --- a/llvm/lib/MC/MCXCOFFStreamer.cpp +++ b/llvm/lib/MC/MCXCOFFStreamer.cpp @@ -10,12 +10,14 @@ // //===----------------------------------------------------------------------===// +#include "llvm/MC/MCXCOFFStreamer.h" #include "llvm/BinaryFormat/XCOFF.h" #include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCObjectWriter.h" +#include "llvm/MC/MCSectionXCOFF.h" #include "llvm/MC/MCSymbolXCOFF.h" -#include "llvm/MC/MCXCOFFStreamer.h" #include "llvm/Support/TargetRegistry.h" using namespace llvm; @@ -27,41 +29,73 @@ MCXCOFFStreamer::MCXCOFFStreamer(MCContext &Context, : MCObjectStreamer(Context, std::move(MAB), std::move(OW), std::move(Emitter)) {} -bool MCXCOFFStreamer::EmitSymbolAttribute(MCSymbol *Sym, +bool MCXCOFFStreamer::emitSymbolAttribute(MCSymbol *Sym, MCSymbolAttr Attribute) { auto *Symbol = cast<MCSymbolXCOFF>(Sym); getAssembler().registerSymbol(*Symbol); switch (Attribute) { case MCSA_Global: + case MCSA_Extern: Symbol->setStorageClass(XCOFF::C_EXT); Symbol->setExternal(true); break; + case MCSA_LGlobal: + Symbol->setStorageClass(XCOFF::C_HIDEXT); + Symbol->setExternal(true); + break; + case llvm::MCSA_Weak: + Symbol->setStorageClass(XCOFF::C_WEAKEXT); + Symbol->setExternal(true); + break; + case llvm::MCSA_Hidden: + Symbol->setVisibilityType(XCOFF::SYM_V_HIDDEN); + break; + case llvm::MCSA_Protected: + Symbol->setVisibilityType(XCOFF::SYM_V_PROTECTED); + break; default: report_fatal_error("Not implemented yet."); } return true; } -void MCXCOFFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, +void MCXCOFFStreamer::emitXCOFFSymbolLinkageWithVisibility( + MCSymbol *Symbol, MCSymbolAttr Linkage, MCSymbolAttr Visibility) { + + emitSymbolAttribute(Symbol, Linkage); + + // When the caller passes `MCSA_Invalid` for the visibility, do not emit one. + if (Visibility == MCSA_Invalid) + return; + + emitSymbolAttribute(Symbol, Visibility); +} + +void MCXCOFFStreamer::emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) { getAssembler().registerSymbol(*Symbol); Symbol->setExternal(cast<MCSymbolXCOFF>(Symbol)->getStorageClass() != XCOFF::C_HIDEXT); Symbol->setCommon(Size, ByteAlignment); + // Default csect align is 4, but common symbols have explicit alignment values + // and we should honor it. + cast<MCSymbolXCOFF>(Symbol)->getRepresentedCsect()->setAlignment( + Align(ByteAlignment)); + // Emit the alignment and storage for the variable to the section. - EmitValueToAlignment(ByteAlignment); - EmitZeros(Size); + emitValueToAlignment(ByteAlignment); + emitZeros(Size); } -void MCXCOFFStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol, +void MCXCOFFStreamer::emitZerofill(MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment, SMLoc Loc) { report_fatal_error("Zero fill not implemented for XCOFF."); } -void MCXCOFFStreamer::EmitInstToData(const MCInst &Inst, +void MCXCOFFStreamer::emitInstToData(const MCInst &Inst, const MCSubtargetInfo &STI) { MCAssembler &Assembler = getAssembler(); SmallVector<MCFixup, 4> Fixups; @@ -69,9 +103,15 @@ void MCXCOFFStreamer::EmitInstToData(const MCInst &Inst, raw_svector_ostream VecOS(Code); Assembler.getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI); - // TODO: Handle Fixups later - + // Add the fixups and data. MCDataFragment *DF = getOrCreateDataFragment(&STI); + const size_t ContentsSize = DF->getContents().size(); + auto &DataFragmentFixups = DF->getFixups(); + for (auto &Fixup : Fixups) { + Fixup.setOffset(Fixup.getOffset() + ContentsSize); + DataFragmentFixups.push_back(Fixup); + } + DF->setHasInstructions(STI); DF->getContents().append(Code.begin(), Code.end()); } @@ -88,9 +128,9 @@ MCStreamer *llvm::createXCOFFStreamer(MCContext &Context, return S; } -void MCXCOFFStreamer::EmitXCOFFLocalCommonSymbol(MCSymbol *LabelSym, +void MCXCOFFStreamer::emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym, uint64_t Size, MCSymbol *CsectSym, unsigned ByteAlignment) { - EmitCommonSymbol(CsectSym, Size, ByteAlignment); + emitCommonSymbol(CsectSym, Size, ByteAlignment); } |