brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.6 KiB · 4bf14c1 Raw
151 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file assembles .s files and emits XCOFF .o object files.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/MC/MCXCOFFStreamer.h"14#include "llvm/BinaryFormat/XCOFF.h"15#include "llvm/MC/MCAsmBackend.h"16#include "llvm/MC/MCAssembler.h"17#include "llvm/MC/MCCodeEmitter.h"18#include "llvm/MC/MCDirectives.h"19#include "llvm/MC/MCObjectWriter.h"20#include "llvm/MC/MCSectionXCOFF.h"21#include "llvm/MC/MCSymbolXCOFF.h"22#include "llvm/MC/MCXCOFFObjectWriter.h"23#include "llvm/MC/TargetRegistry.h"24 25using namespace llvm;26 27MCXCOFFStreamer::MCXCOFFStreamer(MCContext &Context,28                                 std::unique_ptr<MCAsmBackend> MAB,29                                 std::unique_ptr<MCObjectWriter> OW,30                                 std::unique_ptr<MCCodeEmitter> Emitter)31    : MCObjectStreamer(Context, std::move(MAB), std::move(OW),32                       std::move(Emitter)) {}33 34XCOFFObjectWriter &MCXCOFFStreamer::getWriter() {35  return static_cast<XCOFFObjectWriter &>(getAssembler().getWriter());36}37 38void MCXCOFFStreamer::changeSection(MCSection *Section, uint32_t Subsection) {39  MCObjectStreamer::changeSection(Section, Subsection);40  auto *Sec = static_cast<const MCSectionXCOFF *>(Section);41  // We might miss calculating the symbols difference as absolute value before42  // adding fixups when symbol_A without the fragment set is the csect itself43  // and symbol_B is in it.44  // TODO: Currently we only set the fragment for XMC_PR csects and DWARF45  // sections because we don't have other cases that hit this problem yet.46  // if (IsDwarfSec || CsectProp->MappingClass == XCOFF::XMC_PR)47  //   QualName->setFragment(F);48  if (Sec->isDwarfSect() || Sec->getMappingClass() == XCOFF::XMC_PR)49    Sec->getQualNameSymbol()->setFragment(CurFrag);50}51 52bool MCXCOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,53                                          MCSymbolAttr Attribute) {54  auto *Symbol = static_cast<MCSymbolXCOFF *>(Sym);55  getAssembler().registerSymbol(*Symbol);56 57  switch (Attribute) {58  // XCOFF doesn't support the cold feature.59  case MCSA_Cold:60    return false;61 62  case MCSA_Global:63  case MCSA_Extern:64    Symbol->setStorageClass(XCOFF::C_EXT);65    Symbol->setExternal(true);66    break;67  case MCSA_LGlobal:68    Symbol->setStorageClass(XCOFF::C_HIDEXT);69    Symbol->setExternal(true);70    break;71  case llvm::MCSA_Weak:72    Symbol->setStorageClass(XCOFF::C_WEAKEXT);73    Symbol->setExternal(true);74    break;75  case llvm::MCSA_Hidden:76    Symbol->setVisibilityType(XCOFF::SYM_V_HIDDEN);77    break;78  case llvm::MCSA_Protected:79    Symbol->setVisibilityType(XCOFF::SYM_V_PROTECTED);80    break;81  case llvm::MCSA_Exported:82    Symbol->setVisibilityType(XCOFF::SYM_V_EXPORTED);83    break;84  default:85    report_fatal_error("Not implemented yet.");86  }87  return true;88}89 90void MCXCOFFStreamer::emitXCOFFSymbolLinkageWithVisibility(91    MCSymbol *Symbol, MCSymbolAttr Linkage, MCSymbolAttr Visibility) {92 93  emitSymbolAttribute(Symbol, Linkage);94 95  // When the caller passes `MCSA_Invalid` for the visibility, do not emit one.96  if (Visibility == MCSA_Invalid)97    return;98 99  emitSymbolAttribute(Symbol, Visibility);100}101 102void MCXCOFFStreamer::emitXCOFFRefDirective(const MCSymbol *Symbol) {103  // Add a Fixup here to later record a relocation of type R_REF to prevent the104  // ref symbol from being garbage collected (by the binder).105  addFixup(MCSymbolRefExpr::create(Symbol, getContext()),106           XCOFF::RelocationType::R_REF);107}108 109void MCXCOFFStreamer::emitXCOFFRenameDirective(const MCSymbol *Name,110                                               StringRef Rename) {111  auto *Symbol = static_cast<const MCSymbolXCOFF *>(Name);112  if (!Symbol->hasRename())113    report_fatal_error("Only explicit .rename is supported for XCOFF.");114}115 116void MCXCOFFStreamer::emitXCOFFExceptDirective(const MCSymbol *Symbol,117                                               const MCSymbol *Trap,118                                               unsigned Lang, unsigned Reason,119                                               unsigned FunctionSize,120                                               bool hasDebug) {121  getWriter().addExceptionEntry(Symbol, Trap, Lang, Reason, FunctionSize,122                                hasDebug);123}124 125void MCXCOFFStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {126  getWriter().addCInfoSymEntry(Name, Metadata);127}128 129void MCXCOFFStreamer::emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,130                                       Align ByteAlignment) {131  auto &Sym = static_cast<MCSymbolXCOFF &>(*Symbol);132  getAssembler().registerSymbol(*Symbol);133  Sym.setExternal(Sym.getStorageClass() != XCOFF::C_HIDEXT);134  Symbol->setCommon(Size, ByteAlignment);135 136  // Default csect align is 4, but common symbols have explicit alignment values137  // and we should honor it.138  Sym.getRepresentedCsect()->setAlignment(ByteAlignment);139 140  // Emit the alignment and storage for the variable to the section.141  emitValueToAlignment(ByteAlignment);142  emitZeros(Size);143}144 145void MCXCOFFStreamer::emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym,146                                                 uint64_t Size,147                                                 MCSymbol *CsectSym,148                                                 Align Alignment) {149  emitCommonSymbol(CsectSym, Size, Alignment);150}151