128 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			128 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
//===- lib/MC/MCSectionXCOFF.cpp - XCOFF Code Section Representation ------===//
 | 
						|
//
 | 
						|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | 
						|
// See https://llvm.org/LICENSE.txt for license information.
 | 
						|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
#include "llvm/MC/MCSectionXCOFF.h"
 | 
						|
#include "llvm/MC/MCAsmInfo.h"
 | 
						|
#include "llvm/MC/MCExpr.h"
 | 
						|
#include "llvm/Support/Debug.h"
 | 
						|
#include "llvm/Support/Format.h"
 | 
						|
#include "llvm/Support/raw_ostream.h"
 | 
						|
 | 
						|
using namespace llvm;
 | 
						|
 | 
						|
MCSectionXCOFF::~MCSectionXCOFF() = default;
 | 
						|
 | 
						|
void MCSectionXCOFF::printCsectDirective(raw_ostream &OS) const {
 | 
						|
  OS << "\t.csect " << QualName->getName() << "," << Log2_32(getAlignment())
 | 
						|
     << '\n';
 | 
						|
}
 | 
						|
 | 
						|
void MCSectionXCOFF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
 | 
						|
                                          raw_ostream &OS,
 | 
						|
                                          const MCExpr *Subsection) const {
 | 
						|
  if (getKind().isText()) {
 | 
						|
    if (getMappingClass() != XCOFF::XMC_PR)
 | 
						|
      report_fatal_error("Unhandled storage-mapping class for .text csect");
 | 
						|
 | 
						|
    printCsectDirective(OS);
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  if (getKind().isReadOnly()) {
 | 
						|
    if (getMappingClass() != XCOFF::XMC_RO)
 | 
						|
      report_fatal_error("Unhandled storage-mapping class for .rodata csect.");
 | 
						|
    printCsectDirective(OS);
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  // Initialized TLS data.
 | 
						|
  if (getKind().isThreadData()) {
 | 
						|
    // We only expect XMC_TL here for initialized TLS data.
 | 
						|
    if (getMappingClass() != XCOFF::XMC_TL)
 | 
						|
      report_fatal_error("Unhandled storage-mapping class for .tdata csect.");
 | 
						|
    printCsectDirective(OS);
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  if (getKind().isData()) {
 | 
						|
    switch (getMappingClass()) {
 | 
						|
    case XCOFF::XMC_RW:
 | 
						|
    case XCOFF::XMC_DS:
 | 
						|
    case XCOFF::XMC_TD:
 | 
						|
      printCsectDirective(OS);
 | 
						|
      break;
 | 
						|
    case XCOFF::XMC_TC:
 | 
						|
    case XCOFF::XMC_TE:
 | 
						|
      break;
 | 
						|
    case XCOFF::XMC_TC0:
 | 
						|
      OS << "\t.toc\n";
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      report_fatal_error(
 | 
						|
          "Unhandled storage-mapping class for .data csect.");
 | 
						|
    }
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  if (isCsect() && getMappingClass() == XCOFF::XMC_TD) {
 | 
						|
    assert((getKind().isBSSExtern() || getKind().isBSSLocal()) &&
 | 
						|
           "Unexepected section kind for toc-data");
 | 
						|
    printCsectDirective(OS);
 | 
						|
    return;
 | 
						|
  }
 | 
						|
  // Common csect type (uninitialized storage) does not have to print csect
 | 
						|
  // directive for section switching.
 | 
						|
  if (isCsect() && getCSectType() == XCOFF::XTY_CM) {
 | 
						|
    assert((getMappingClass() == XCOFF::XMC_RW ||
 | 
						|
            getMappingClass() == XCOFF::XMC_BS ||
 | 
						|
            getMappingClass() == XCOFF::XMC_UL) &&
 | 
						|
           "Generated a storage-mapping class for a common/bss/tbss csect we "
 | 
						|
           "don't "
 | 
						|
           "understand how to switch to.");
 | 
						|
    // Common symbols and local zero-initialized symbols for TLS and Non-TLS are
 | 
						|
    // eligible for .bss/.tbss csect, getKind().isThreadBSS() is used to cover
 | 
						|
    // TLS common and zero-initialized local symbols since linkage type (in the
 | 
						|
    // GlobalVariable) is not accessible in this class.
 | 
						|
    assert((getKind().isBSSLocal() || getKind().isCommon() ||
 | 
						|
            getKind().isThreadBSS()) &&
 | 
						|
           "wrong symbol type for .bss/.tbss csect");
 | 
						|
    // Don't have to print a directive for switching to section for commons and
 | 
						|
    // zero-initialized TLS data. The '.comm' and '.lcomm' directives of the
 | 
						|
    // variable will create the needed csect.
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  // Zero-initialized TLS data with weak or external linkage are not eligible to
 | 
						|
  // be put into common csect.
 | 
						|
  if (getKind().isThreadBSS()) {
 | 
						|
    printCsectDirective(OS);
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  // XCOFF debug sections.
 | 
						|
  if (getKind().isMetadata() && isDwarfSect()) {
 | 
						|
    OS << "\n\t.dwsect "
 | 
						|
       << format("0x%" PRIx32, getDwarfSubtypeFlags().getValue()) << '\n';
 | 
						|
    OS << MAI.getPrivateLabelPrefix() << getName() << ':' << '\n';
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  report_fatal_error("Printing for this SectionKind is unimplemented.");
 | 
						|
}
 | 
						|
 | 
						|
bool MCSectionXCOFF::UseCodeAlign() const { return getKind().isText(); }
 | 
						|
 | 
						|
bool MCSectionXCOFF::isVirtualSection() const {
 | 
						|
  // DWARF sections are always not virtual.
 | 
						|
  if (isDwarfSect())
 | 
						|
    return false;
 | 
						|
  assert(isCsect() &&
 | 
						|
         "Handling for isVirtualSection not implemented for this section!");
 | 
						|
  return XCOFF::XTY_CM == CsectProp->Type;
 | 
						|
}
 |