aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/MC/MCSection.cpp
blob: 21ba41007e257e7da197e86de19eb284ff4e6189 (plain)
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
// 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