1 //===- lib/MC/MCXCOFFStreamer.cpp - XCOFF Object Output -------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file assembles .s files and emits XCOFF .o object files. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/BinaryFormat/XCOFF.h" 14 #include "llvm/MC/MCAsmBackend.h" 15 #include "llvm/MC/MCCodeEmitter.h" 16 #include "llvm/MC/MCObjectWriter.h" 17 #include "llvm/MC/MCSymbolXCOFF.h" 18 #include "llvm/MC/MCXCOFFStreamer.h" 19 #include "llvm/Support/TargetRegistry.h" 20 21 using namespace llvm; 22 23 MCXCOFFStreamer::MCXCOFFStreamer(MCContext &Context, 24 std::unique_ptr<MCAsmBackend> MAB, 25 std::unique_ptr<MCObjectWriter> OW, 26 std::unique_ptr<MCCodeEmitter> Emitter) 27 : MCObjectStreamer(Context, std::move(MAB), std::move(OW), 28 std::move(Emitter)) {} 29 30 bool MCXCOFFStreamer::EmitSymbolAttribute(MCSymbol *Sym, 31 MCSymbolAttr Attribute) { 32 auto *Symbol = cast<MCSymbolXCOFF>(Sym); 33 getAssembler().registerSymbol(*Symbol); 34 35 switch (Attribute) { 36 case MCSA_Global: 37 Symbol->setStorageClass(XCOFF::C_EXT); 38 Symbol->setExternal(true); 39 break; 40 default: 41 report_fatal_error("Not implemented yet."); 42 } 43 return true; 44 } 45 46 void MCXCOFFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 47 unsigned ByteAlignment) { 48 getAssembler().registerSymbol(*Symbol); 49 Symbol->setExternal(cast<MCSymbolXCOFF>(Symbol)->getStorageClass() != 50 XCOFF::C_HIDEXT); 51 Symbol->setCommon(Size, ByteAlignment); 52 53 // Need to add this symbol to the current Fragment which will belong to the 54 // containing CSECT. 55 auto *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment()); 56 assert(F && "Expected a valid section with a fragment set."); 57 Symbol->setFragment(F); 58 59 // Emit the alignment and storage for the variable to the section. 60 EmitValueToAlignment(ByteAlignment); 61 EmitZeros(Size); 62 } 63 64 void MCXCOFFStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol, 65 uint64_t Size, unsigned ByteAlignment, 66 SMLoc Loc) { 67 report_fatal_error("Zero fill not implemented for XCOFF."); 68 } 69 70 void MCXCOFFStreamer::EmitInstToData(const MCInst &Inst, 71 const MCSubtargetInfo &STI) { 72 MCAssembler &Assembler = getAssembler(); 73 SmallVector<MCFixup, 4> Fixups; 74 SmallString<256> Code; 75 raw_svector_ostream VecOS(Code); 76 Assembler.getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI); 77 78 // TODO: Handle Fixups later 79 80 MCDataFragment *DF = getOrCreateDataFragment(&STI); 81 DF->setHasInstructions(STI); 82 DF->getContents().append(Code.begin(), Code.end()); 83 } 84 85 MCStreamer *llvm::createXCOFFStreamer(MCContext &Context, 86 std::unique_ptr<MCAsmBackend> &&MAB, 87 std::unique_ptr<MCObjectWriter> &&OW, 88 std::unique_ptr<MCCodeEmitter> &&CE, 89 bool RelaxAll) { 90 MCXCOFFStreamer *S = new MCXCOFFStreamer(Context, std::move(MAB), 91 std::move(OW), std::move(CE)); 92 if (RelaxAll) 93 S->getAssembler().setRelaxAll(true); 94 return S; 95 } 96 97 void MCXCOFFStreamer::EmitXCOFFLocalCommonSymbol(MCSymbol *Symbol, 98 uint64_t Size, 99 unsigned ByteAlignment) { 100 EmitCommonSymbol(Symbol, Size, ByteAlignment); 101 } 102