aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/MC/MCSection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'backend/lib/MC/MCSection.cpp')
-rw-r--r--backend/lib/MC/MCSection.cpp60
1 files changed, 60 insertions, 0 deletions
diff --git a/backend/lib/MC/MCSection.cpp b/backend/lib/MC/MCSection.cpp
new file mode 100644
index 0000000..21ba410
--- /dev/null
+++ b/backend/lib/MC/MCSection.cpp
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "rcc/MC/MCSection.h"
+
+#include <cstdint>
+#include <string_view>
+
+namespace rcc::mc {
+namespace {
+
+[[nodiscard]] bool isValidAssemblyName(std::string_view Name) noexcept {
+ if (Name.empty())
+ return false;
+ for (const char RawCharacter : Name) {
+ const auto Character = static_cast<unsigned char>(RawCharacter);
+ if (Character == 0 || Character == '\n' || Character == '\r' || Character == 0x7fU)
+ return false;
+ }
+ return true;
+}
+
+[[nodiscard]] bool isPowerOfTwo(std::uint64_t Value) noexcept {
+ return Value != 0 && (Value & (Value - 1U)) == 0;
+}
+
+} // namespace
+
+Expected<void> MCSectionDesc::verify() const {
+ if (!isValidAssemblyName(Name))
+ return makeUnexpected(ErrorCode::InvalidArgument, "MC section has an invalid name");
+ if (!isPowerOfTwo(Alignment)) {
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "MC section alignment must be a nonzero power of two");
+ }
+ if (Flags.has(MCSectionFlag::Strings) && !Flags.has(MCSectionFlag::Merge)) {
+ return makeUnexpected(ErrorCode::InvalidArgument, "string MC sections must also be mergeable");
+ }
+ if (Flags.has(MCSectionFlag::Merge) && EntrySize == 0) {
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "mergeable MC sections require a nonzero entry size");
+ }
+ if ((Kind == MCSectionKind::TLSData || Kind == MCSectionKind::TLSBSS) &&
+ !Flags.has(MCSectionFlag::TLS)) {
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "TLS MC sections must carry the TLS section flag");
+ }
+ if (Flags.has(MCSectionFlag::Group) != static_cast<bool>(Group)) {
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "MC section group flag and group symbol must agree");
+ }
+ if (Group && Group->name().empty()) {
+ return makeUnexpected(ErrorCode::InvalidArgument, "MC section group symbol must have a name");
+ }
+ if (UniqueID && *UniqueID == 0) {
+ return makeUnexpected(ErrorCode::InvalidArgument, "unique MC section identity must be nonzero");
+ }
+ return {};
+}
+
+} // namespace rcc::mc