summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r--llvm/lib/MC/CMakeLists.txt5
-rw-r--r--llvm/lib/MC/MCAsmBackend.cpp4
-rw-r--r--llvm/lib/MC/MCAsmInfoXCOFF.cpp18
-rw-r--r--llvm/lib/MC/MCContext.cpp35
-rw-r--r--llvm/lib/MC/MCObjectFileInfo.cpp13
-rw-r--r--llvm/lib/MC/MCSectionXCOFF.cpp33
-rw-r--r--llvm/lib/MC/MCXCOFFObjectTargetWriter.cpp16
-rw-r--r--llvm/lib/MC/MCXCOFFStreamer.cpp59
-rw-r--r--llvm/lib/MC/XCOFFObjectWriter.cpp94
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);
+}
OpenPOWER on IntegriCloud