diff options
| author | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-09 22:05:14 +0800 |
|---|---|---|
| committer | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-09 22:05:14 +0800 |
| commit | 3a57627e59ba18b6f9f9aae7bb60c390c0d3575a (patch) | |
| tree | 736ca062bfffbd68177a512dfe145b06c16d11b1 /backend/lib/MC/MCObjectStreamer.cpp | |
| parent | 379ff50dcc7ccf977379aee68fa9d10f69065d23 (diff) | |
| download | rcc-project-3a57627e59ba18b6f9f9aae7bb60c390c0d3575a.tar.gz rcc-project-3a57627e59ba18b6f9f9aae7bb60c390c0d3575a.tar.xz | |
[MC] Implement RV64GC object emission
Diffstat (limited to 'backend/lib/MC/MCObjectStreamer.cpp')
| -rw-r--r-- | backend/lib/MC/MCObjectStreamer.cpp | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/backend/lib/MC/MCObjectStreamer.cpp b/backend/lib/MC/MCObjectStreamer.cpp new file mode 100644 index 0000000..634b713 --- /dev/null +++ b/backend/lib/MC/MCObjectStreamer.cpp @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "rcc/MC/MCObjectStreamer.h" + +#include <utility> + +namespace rcc::mc { + +Expected<void> ELFObjectStreamer::ensureOpen() const { + if (IsFinished) + return makeUnexpected(ErrorCode::ObjectWritingFailed, "object stream is already finalized"); + return {}; +} + +Expected<void> ELFObjectStreamer::switchSection(MCSectionRef Section) { + auto Open = ensureOpen(); + return Open ? Assembler.switchSection(std::move(Section)) : Open; +} + +Expected<void> ELFObjectStreamer::emitLabel(MCSymbolRef Symbol) { + auto Open = ensureOpen(); + return Open ? Assembler.emitLabel(std::move(Symbol)) : Open; +} + +Expected<void> ELFObjectStreamer::emitInstruction(const MCInst &Instruction) { + auto Open = ensureOpen(); + return Open ? Assembler.emitInstruction(Instruction) : Open; +} + +Expected<void> ELFObjectStreamer::emitValue(MCExprRef Value, std::uint8_t Size) { + auto Open = ensureOpen(); + return Open ? Assembler.emitValue(std::move(Value), Size) : Open; +} + +Expected<void> ELFObjectStreamer::emitBytes(std::span<const std::uint8_t> Bytes) { + auto Open = ensureOpen(); + return Open ? Assembler.emitBytes(Bytes) : Open; +} + +Expected<void> ELFObjectStreamer::emitZeroFill(std::uint64_t Size) { + auto Open = ensureOpen(); + return Open ? Assembler.emitZeroFill(Size) : Open; +} + +Expected<void> ELFObjectStreamer::emitAlignment(std::uint64_t Alignment, std::uint8_t Fill, + std::uint64_t MaximumBytes) { + auto Open = ensureOpen(); + return Open ? Assembler.emitAlignment(Alignment, Fill, MaximumBytes) : Open; +} + +Expected<void> ELFObjectStreamer::emitSymbolAttribute(MCSymbolRef Symbol, + MCSymbolAttribute Attribute) { + auto Open = ensureOpen(); + return Open ? Assembler.emitSymbolAttribute(std::move(Symbol), Attribute) : Open; +} + +Expected<void> ELFObjectStreamer::emitSymbolSize(MCSymbolRef Symbol, MCExprRef Size) { + auto Open = ensureOpen(); + return Open ? Assembler.emitSymbolSize(std::move(Symbol), std::move(Size)) : Open; +} + +Expected<void> ELFObjectStreamer::emitCommonSymbol(MCSymbolRef Symbol, std::uint64_t Size, + std::uint64_t Alignment) { + auto Open = ensureOpen(); + return Open ? Assembler.emitCommonSymbol(std::move(Symbol), Size, Alignment) : Open; +} + +Expected<void> ELFObjectStreamer::emitDirective(std::string_view Name, std::string_view) { + auto Open = ensureOpen(); + if (!Open) + return Open; + if (Name == "attribute") + return {}; + return makeUnexpected(ErrorCode::Unsupported, + "native object emission does not support the MC directive '" + + std::string(Name) + "'"); +} + +Expected<void> ELFObjectStreamer::emitCFI(const MCCFIInstruction &Instruction) { + auto Open = ensureOpen(); + if (!Open) + return Open; + return Assembler.emitCFI(Instruction); +} + +Expected<void> ELFObjectStreamer::emitInlineAssembly(std::string_view Text) { + auto Open = ensureOpen(); + if (!Open) + return Open; + if (Text.empty()) + return {}; + return makeUnexpected(ErrorCode::Unsupported, + "native object emission requires parsed inline assembly"); +} + +Expected<void> ELFObjectStreamer::emitComment(std::string_view) { + return ensureOpen(); +} + +Expected<void> ELFObjectStreamer::configureDwarfFrame(MCSectionRef Section, MCDwarfFrameInfo Info) { + auto Open = ensureOpen(); + if (!Open) + return Open; + return Assembler.configureDwarfFrame(std::move(Section), Info); +} + +Expected<void> ELFObjectStreamer::finish() { + auto Open = ensureOpen(); + if (!Open) + return Open; + auto Object = Assembler.assemble(); + if (!Object) + return std::unexpected(Object.error()); + auto Written = Writer->writeObject(*Object); + if (!Written) + return std::unexpected(Written.error()); + Output = std::move(*Written); + IsFinished = true; + return {}; +} + +Expected<std::vector<std::uint8_t>> ELFObjectStreamer::takeOutput() { + if (!IsFinished) + return makeUnexpected(ErrorCode::ObjectWritingFailed, + "object output cannot be taken before finalization"); + if (OutputWasTaken) + return makeUnexpected(ErrorCode::ObjectWritingFailed, "object output was already taken"); + OutputWasTaken = true; + return std::move(Output); +} + +} // namespace rcc::mc |
