aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/MC/MCXCOFFStreamer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/MC/MCXCOFFStreamer.cpp')
-rw-r--r--llvm/lib/MC/MCXCOFFStreamer.cpp62
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);
}