diff options
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r-- | llvm/lib/MC/CMakeLists.txt | 5 | ||||
-rw-r--r-- | llvm/lib/MC/MCAsmBackend.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/MC/MCAsmInfoXCOFF.cpp | 18 | ||||
-rw-r--r-- | llvm/lib/MC/MCContext.cpp | 35 | ||||
-rw-r--r-- | llvm/lib/MC/MCObjectFileInfo.cpp | 13 | ||||
-rw-r--r-- | llvm/lib/MC/MCSectionXCOFF.cpp | 33 | ||||
-rw-r--r-- | llvm/lib/MC/MCXCOFFObjectTargetWriter.cpp | 16 | ||||
-rw-r--r-- | llvm/lib/MC/MCXCOFFStreamer.cpp | 59 | ||||
-rw-r--r-- | llvm/lib/MC/XCOFFObjectWriter.cpp | 94 |
9 files changed, 275 insertions, 2 deletions
diff --git a/llvm/lib/MC/CMakeLists.txt b/llvm/lib/MC/CMakeLists.txt index ba36d99e8f7..14e965b55fd 100644 --- a/llvm/lib/MC/CMakeLists.txt +++ b/llvm/lib/MC/CMakeLists.txt @@ -7,6 +7,7 @@ add_llvm_library(LLVMMC MCAsmInfoDarwin.cpp MCAsmInfoELF.cpp MCAsmInfoWasm.cpp + MCAsmInfoXCOFF.cpp MCAsmMacro.cpp MCAsmStreamer.cpp MCAssembler.cpp @@ -38,6 +39,7 @@ add_llvm_library(LLVMMC MCSectionELF.cpp MCSectionMachO.cpp MCSectionWasm.cpp + MCSectionXCOFF.cpp MCStreamer.cpp MCSubtargetInfo.cpp MCSymbol.cpp @@ -49,11 +51,14 @@ add_llvm_library(LLVMMC MCWin64EH.cpp MCWinCOFFStreamer.cpp MCWinEH.cpp + MCXCOFFObjectTargetWriter.cpp + MCXCOFFStreamer.cpp MachObjectWriter.cpp StringTableBuilder.cpp SubtargetFeature.cpp WasmObjectWriter.cpp WinCOFFObjectWriter.cpp + XCOFFObjectWriter.cpp ADDITIONAL_HEADER_DIRS ${LLVM_MAIN_INCLUDE_DIR}/llvm/MC diff --git a/llvm/lib/MC/MCAsmBackend.cpp b/llvm/lib/MC/MCAsmBackend.cpp index 912bec91961..9b1102cbe7d 100644 --- a/llvm/lib/MC/MCAsmBackend.cpp +++ b/llvm/lib/MC/MCAsmBackend.cpp @@ -16,6 +16,7 @@ #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCWasmObjectWriter.h" #include "llvm/MC/MCWinCOFFObjectWriter.h" +#include "llvm/MC/MCXCOFFObjectWriter.h" #include <cassert> #include <cstddef> #include <cstdint> @@ -43,6 +44,9 @@ MCAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const { case Triple::Wasm: return createWasmObjectWriter(cast<MCWasmObjectTargetWriter>(std::move(TW)), OS); + case Triple::XCOFF: + return createXCOFFObjectWriter( + cast<MCXCOFFObjectTargetWriter>(std::move(TW)), OS); default: llvm_unreachable("unexpected object format"); } diff --git a/llvm/lib/MC/MCAsmInfoXCOFF.cpp b/llvm/lib/MC/MCAsmInfoXCOFF.cpp new file mode 100644 index 00000000000..74c21f0c9e6 --- /dev/null +++ b/llvm/lib/MC/MCAsmInfoXCOFF.cpp @@ -0,0 +1,18 @@ +//===- MC/MCAsmInfoXCOFF.cpp - XCOFF asm properties ------------ *- C++ -*-===// +// +// 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/MCAsmInfoXCOFF.h" + +using namespace llvm; + +void MCAsmInfoXCOFF::anchor() {} + +MCAsmInfoXCOFF::MCAsmInfoXCOFF() { + IsLittleEndian = false; + HasDotTypeDotSizeDirective = false; +} diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp index 5ec03ee0894..0dc2e2d37ca 100644 --- a/llvm/lib/MC/MCContext.cpp +++ b/llvm/lib/MC/MCContext.cpp @@ -26,6 +26,7 @@ #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCSectionWasm.h" +#include "llvm/MC/MCSectionXCOFF.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCSymbolCOFF.h" @@ -86,6 +87,7 @@ void MCContext::reset() { COFFAllocator.DestroyAll(); ELFAllocator.DestroyAll(); MachOAllocator.DestroyAll(); + XCOFFAllocator.DestroyAll(); MCSubtargetAllocator.DestroyAll(); UsedNames.clear(); @@ -107,6 +109,7 @@ void MCContext::reset() { ELFUniquingMap.clear(); COFFUniquingMap.clear(); WasmUniquingMap.clear(); + XCOFFUniquingMap.clear(); NextID.clear(); AllowTemporaryLabels = true; @@ -526,6 +529,38 @@ MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind Kind, return Result; } +MCSectionXCOFF *MCContext::getXCOFFSection(StringRef Section, + XCOFF::StorageMappingClass SMC, + SectionKind Kind, + const char *BeginSymName) { + // Do the lookup. If we have a hit, return it. + auto IterBool = XCOFFUniquingMap.insert( + std::make_pair(XCOFFSectionKey{Section.str(), SMC}, nullptr)); + auto &Entry = *IterBool.first; + if (!IterBool.second) + return Entry.second; + + // Otherwise, return a new section. + StringRef CachedName = Entry.first.SectionName; + + MCSymbol *Begin = nullptr; + if (BeginSymName) + Begin = createTempSymbol(BeginSymName, false); + + MCSectionXCOFF *Result = new (XCOFFAllocator.Allocate()) + MCSectionXCOFF(CachedName, SMC, Kind, Begin); + Entry.second = Result; + + auto *F = new MCDataFragment(); + Result->getFragmentList().insert(Result->begin(), F); + F->setParent(Result); + + if (Begin) + Begin->setFragment(F); + + return Result; +} + MCSubtargetInfo &MCContext::getSubtargetCopy(const MCSubtargetInfo &STI) { return *new (MCSubtargetAllocator.Allocate()) MCSubtargetInfo(STI); } diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp index 0faa236c153..9f555abe140 100644 --- a/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/llvm/lib/MC/MCObjectFileInfo.cpp @@ -18,6 +18,7 @@ #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCSectionWasm.h" +#include "llvm/MC/MCSectionXCOFF.h" using namespace llvm; @@ -761,6 +762,15 @@ void MCObjectFileInfo::initWasmMCObjectFileInfo(const Triple &T) { // TODO: Define more sections. } +void MCObjectFileInfo::initXCOFFMCObjectFileInfo(const Triple &T) { + // The default csect for program code. Functions without a specified section + // get placed into this csect. The choice of csect name is not a property of + // the ABI or object file format. For example, the XL compiler uses an unnamed + // csect for program code. + TextSection = Ctx->getXCOFFSection( + ".text", XCOFF::StorageMappingClass::XMC_PR, SectionKind::getText()); +} + void MCObjectFileInfo::InitMCObjectFileInfo(const Triple &TheTriple, bool PIC, MCContext &ctx, bool LargeCodeModel) { @@ -809,8 +819,7 @@ void MCObjectFileInfo::InitMCObjectFileInfo(const Triple &TheTriple, bool PIC, break; case Triple::XCOFF: Env = IsXCOFF; - // TODO: Initialize MCObjectFileInfo for XCOFF format when - // MCSectionXCOFF is ready. + initXCOFFMCObjectFileInfo(TT); break; case Triple::UnknownObjectFormat: report_fatal_error("Cannot initialize MC for unknown object file format."); diff --git a/llvm/lib/MC/MCSectionXCOFF.cpp b/llvm/lib/MC/MCSectionXCOFF.cpp new file mode 100644 index 00000000000..d1a63734502 --- /dev/null +++ b/llvm/lib/MC/MCSectionXCOFF.cpp @@ -0,0 +1,33 @@ +//===- 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/raw_ostream.h" + +using namespace llvm; + +MCSectionXCOFF::~MCSectionXCOFF() = default; + +void MCSectionXCOFF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T, + raw_ostream &OS, + const MCExpr *Subsection) const { + if (getKind().isText()) { + OS << "\t.csect " << getSectionName() << "[" + << "PR" + << "]" << '\n'; + return; + } + + report_fatal_error("Printing for this SectionKind is unimplemented."); +} + +bool MCSectionXCOFF::UseCodeAlign() const { return getKind().isText(); } + +bool MCSectionXCOFF::isVirtualSection() const { return !getKind().isCommon(); } diff --git a/llvm/lib/MC/MCXCOFFObjectTargetWriter.cpp b/llvm/lib/MC/MCXCOFFObjectTargetWriter.cpp new file mode 100644 index 00000000000..504e333cb2d --- /dev/null +++ b/llvm/lib/MC/MCXCOFFObjectTargetWriter.cpp @@ -0,0 +1,16 @@ +//===- MCXCOFFObjectTargetWriter.cpp - XCOFF Target Writer Subclass -------===// +// +// 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/MCXCOFFObjectWriter.h" + +using namespace llvm; + +MCXCOFFObjectTargetWriter::MCXCOFFObjectTargetWriter(bool Is64Bit) + : Is64Bit(Is64Bit) {} + +MCXCOFFObjectTargetWriter::~MCXCOFFObjectTargetWriter() = default; diff --git a/llvm/lib/MC/MCXCOFFStreamer.cpp b/llvm/lib/MC/MCXCOFFStreamer.cpp new file mode 100644 index 00000000000..071de024a3f --- /dev/null +++ b/llvm/lib/MC/MCXCOFFStreamer.cpp @@ -0,0 +1,59 @@ +//===- lib/MC/MCXCOFFStreamer.cpp - XCOFF Object Output -------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file assembles .s files and emits XCOFF .o object files. +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCXCOFFStreamer.h" +#include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/Support/TargetRegistry.h" + +using namespace llvm; + +MCXCOFFStreamer::MCXCOFFStreamer(MCContext &Context, + std::unique_ptr<MCAsmBackend> MAB, + std::unique_ptr<MCObjectWriter> OW, + std::unique_ptr<MCCodeEmitter> Emitter) + : MCObjectStreamer(Context, std::move(MAB), std::move(OW), + std::move(Emitter)) {} + +bool MCXCOFFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, + MCSymbolAttr Attribute) { + report_fatal_error("Symbol attributes not implemented for XCOFF."); +} + +void MCXCOFFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) { + report_fatal_error("Emiting common symbols not implemented for XCOFF."); +} + +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, + const MCSubtargetInfo &) { + report_fatal_error("Instruction emission not implemented for XCOFF."); +} + +MCStreamer *llvm::createXCOFFStreamer(MCContext &Context, + std::unique_ptr<MCAsmBackend> &&MAB, + std::unique_ptr<MCObjectWriter> &&OW, + std::unique_ptr<MCCodeEmitter> &&CE, + bool RelaxAll) { + MCXCOFFStreamer *S = new MCXCOFFStreamer(Context, std::move(MAB), + std::move(OW), std::move(CE)); + if (RelaxAll) + S->getAssembler().setRelaxAll(true); + return S; +} diff --git a/llvm/lib/MC/XCOFFObjectWriter.cpp b/llvm/lib/MC/XCOFFObjectWriter.cpp new file mode 100644 index 00000000000..ea586d6b527 --- /dev/null +++ b/llvm/lib/MC/XCOFFObjectWriter.cpp @@ -0,0 +1,94 @@ +//===-- lib/MC/XCOFFObjectWriter.cpp - XCOFF file writer ------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file implements XCOFF object file writer information. +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/MC/MCValue.h" +#include "llvm/MC/MCXCOFFObjectWriter.h" + +using namespace llvm; + +namespace { + +class XCOFFObjectWriter : public MCObjectWriter { + support::endian::Writer W; + std::unique_ptr<MCXCOFFObjectTargetWriter> TargetObjectWriter; + + void executePostLayoutBinding(MCAssembler &, const MCAsmLayout &) override; + + void recordRelocation(MCAssembler &, const MCAsmLayout &, const MCFragment *, + const MCFixup &, MCValue, uint64_t &) override; + + uint64_t writeObject(MCAssembler &, const MCAsmLayout &) override; + +public: + XCOFFObjectWriter(std::unique_ptr<MCXCOFFObjectTargetWriter> MOTW, + raw_pwrite_stream &OS); +}; + +XCOFFObjectWriter::XCOFFObjectWriter( + std::unique_ptr<MCXCOFFObjectTargetWriter> MOTW, raw_pwrite_stream &OS) + : W(OS, support::big), TargetObjectWriter(std::move(MOTW)) {} + +void XCOFFObjectWriter::executePostLayoutBinding(MCAssembler &, + const MCAsmLayout &) { + // TODO Implement once we have sections and symbols to handle. +} + +void XCOFFObjectWriter::recordRelocation(MCAssembler &, const MCAsmLayout &, + const MCFragment *, const MCFixup &, + MCValue, uint64_t &) { + report_fatal_error("XCOFF relocations not supported."); +} + +uint64_t XCOFFObjectWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &) { + // We always emit a timestamp of 0 for reproducibility, so ensure incremental + // linking is not enabled, in case, like with Windows COFF, such a timestamp + // is incompatible with incremental linking of XCOFF. + if (Asm.isIncrementalLinkerCompatible()) + report_fatal_error("Incremental linking not supported for XCOFF."); + + if (TargetObjectWriter->is64Bit()) + report_fatal_error("64-bit XCOFF object files are not supported yet."); + + uint64_t StartOffset = W.OS.tell(); + + // TODO FIXME Assign section numbers/finalize sections. + + // TODO FIXME Finalize symbols. + + // Magic. + W.write<uint16_t>(0x01df); + // Number of sections. + W.write<uint16_t>(0); + // Timestamp field. For reproducible output we write a 0, which represents no + // timestamp. + W.write<int32_t>(0); + // Byte Offset to the start of the symbol table. + W.write<uint32_t>(0); + // Number of entries in the symbol table. + W.write<int32_t>(0); + // Size of the optional header. + W.write<uint16_t>(0); + // Flags. + W.write<uint16_t>(0); + + return W.OS.tell() - StartOffset; +} + +} // end anonymous namespace + +std::unique_ptr<MCObjectWriter> +llvm::createXCOFFObjectWriter(std::unique_ptr<MCXCOFFObjectTargetWriter> MOTW, + raw_pwrite_stream &OS) { + return make_unique<XCOFFObjectWriter>(std::move(MOTW), OS); +} |