1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef RCC_MC_MCASSEMBLER_H
#define RCC_MC_MCASSEMBLER_H
#include "rcc/MC/MCAsmBackend.h"
#include "rcc/MC/MCCodeEmitter.h"
#include "rcc/MC/MCDwarfFrameEmitter.h"
#include "rcc/MC/MCObjectWriter.h"
#include "rcc/MC/MCStreamer.h"
#include "rcc/Support/Error.h"
#include <cstddef>
#include <cstdint>
#include <memory>
#include <optional>
#include <span>
#include <unordered_map>
#include <variant>
#include <vector>
namespace rcc::mc {
class MCAssembler final {
public:
MCAssembler(const MCCodeEmitter &Emitter, const MCAsmBackend &Backend) noexcept
: Emitter(&Emitter), Backend(&Backend) {}
[[nodiscard]] Expected<void> switchSection(MCSectionRef Section);
[[nodiscard]] Expected<void> emitLabel(MCSymbolRef Symbol);
[[nodiscard]] Expected<void> emitInstruction(const MCInst &Instruction);
[[nodiscard]] Expected<void> emitValue(MCExprRef Value, std::uint8_t Size);
[[nodiscard]] Expected<void> emitBytes(std::span<const std::uint8_t> Bytes);
[[nodiscard]] Expected<void> emitZeroFill(std::uint64_t Size);
[[nodiscard]] Expected<void> emitAlignment(std::uint64_t Alignment, std::uint8_t Fill,
std::uint64_t MaximumBytes);
[[nodiscard]] Expected<void> emitSymbolAttribute(MCSymbolRef Symbol, MCSymbolAttribute Attribute);
[[nodiscard]] Expected<void> emitSymbolSize(MCSymbolRef Symbol, MCExprRef Size);
[[nodiscard]] Expected<void> emitCommonSymbol(MCSymbolRef Symbol, std::uint64_t Size,
std::uint64_t Alignment);
[[nodiscard]] Expected<void> emitCFI(const MCCFIInstruction &Instruction);
[[nodiscard]] Expected<void> configureDwarfFrame(MCSectionRef Section, MCDwarfFrameInfo Info);
[[nodiscard]] Expected<MCAssembledObject> assemble();
private:
struct InstructionFragment final {
MCInst Instruction;
};
struct DataFragment final {
std::vector<std::uint8_t> Bytes;
std::vector<MCFixup> Fixups;
};
struct AlignmentFragment final {
std::uint64_t Alignment = 1;
std::uint8_t Fill = 0;
std::uint64_t MaximumBytes = 0;
};
struct ZeroFillFragment final {
std::uint64_t Size = 0;
};
using FragmentPayload =
std::variant<InstructionFragment, DataFragment, AlignmentFragment, ZeroFillFragment>;
struct Fragment final {
FragmentPayload Payload;
std::uint64_t Offset = 0;
std::uint64_t Size = 0;
std::vector<std::uint8_t> EncodedBytes;
std::vector<MCFixup> Fixups;
};
struct SectionData final {
MCSectionRef Section;
std::vector<Fragment> Fragments;
std::uint64_t AddressSize = 0;
std::uint64_t Alignment = 1;
};
struct SymbolData final {
MCSymbolRef Symbol;
MCObjectSymbolBinding Binding = MCObjectSymbolBinding::Local;
bool BindingWasSet = false;
MCObjectSymbolType Type = MCObjectSymbolType::None;
MCObjectSymbolVisibility Visibility = MCObjectSymbolVisibility::Default;
std::optional<std::size_t> SectionIndex;
std::size_t FragmentIndex = 0;
MCExprRef Size;
std::uint64_t CommonSize = 0;
std::uint64_t CommonAlignment = 0;
};
struct CFIEvent final {
MCCFIInstruction Instruction;
std::size_t FragmentIndex = 0;
};
struct CFIProcedure final {
MCSymbolRef Function;
std::size_t SectionIndex = 0;
std::size_t BeginFragmentIndex = 0;
std::size_t EndFragmentIndex = 0;
std::vector<CFIEvent> Events;
bool IsClosed = false;
};
[[nodiscard]] Expected<std::size_t> currentSectionIndex() const;
[[nodiscard]] SymbolData &getOrCreateSymbol(MCSymbolRef Symbol);
[[nodiscard]] Expected<void> encodeFragments();
[[nodiscard]] Expected<bool> layoutAndRelax();
[[nodiscard]] Expected<MCAssembledObject> finalizeObject();
[[nodiscard]] Expected<void> appendDwarfFrame(MCAssembledObject &Object) const;
[[nodiscard]] std::optional<std::uint64_t> symbolOffset(const SymbolData &Symbol) const;
const MCCodeEmitter *Emitter;
const MCAsmBackend *Backend;
std::vector<SectionData> Sections;
std::unordered_map<const MCSection *, std::size_t> SectionIndices;
std::vector<SymbolData> Symbols;
std::unordered_map<const MCSymbol *, std::size_t> SymbolIndices;
std::optional<std::size_t> CurrentSection;
std::vector<CFIProcedure> CFIProcedures;
std::optional<std::size_t> ActiveCFIProcedure;
MCSectionRef EHFrameSection;
std::optional<MCDwarfFrameInfo> DwarfFrameInfo;
bool WasAssembled = false;
};
} // namespace rcc::mc
#endif // RCC_MC_MCASSEMBLER_H
|