if (SE.size().getValue() % sizeof(uintptr_t)) {
std::ostringstream ErrMsg;
ErrMsg << std::hex << "Size of " << SectionName << " 0x"
- << SE.StartAddress.getValue() << " -- 0x" << SE.EndAddress.getValue()
+ << SE.Start.getValue() << " -- 0x" << SE.End.getValue()
<< " is not a pointer multiple";
return make_error<StringError>(ErrMsg.str());
}
Error ELFNixPlatformRuntimeState::registerObjectSections(
ELFNixPerObjectSectionsToRegister POSR) {
- if (POSR.EHFrameSection.StartAddress)
- __register_frame(POSR.EHFrameSection.StartAddress.toPtr<const char *>());
+ if (POSR.EHFrameSection.Start)
+ __register_frame(POSR.EHFrameSection.Start.toPtr<const char *>());
- if (POSR.ThreadDataSection.StartAddress) {
+ if (POSR.ThreadDataSection.Start) {
if (auto Err = registerThreadDataSection(
POSR.ThreadDataSection.toSpan<const char>()))
return Err;
Error ELFNixPlatformRuntimeState::deregisterObjectSections(
ELFNixPerObjectSectionsToRegister POSR) {
- if (POSR.EHFrameSection.StartAddress)
- __deregister_frame(POSR.EHFrameSection.StartAddress.toPtr<const char *>());
+ if (POSR.EHFrameSection.Start)
+ __deregister_frame(POSR.EHFrameSection.Start.toPtr<const char *>());
return Error::success();
}
/// Represents an address range in the exceutor process.
struct ExecutorAddrRange {
ExecutorAddrRange() = default;
- ExecutorAddrRange(ExecutorAddr StartAddress, ExecutorAddr EndAddress)
- : StartAddress(StartAddress), EndAddress(EndAddress) {}
+ ExecutorAddrRange(ExecutorAddr Start, ExecutorAddr End)
+ : Start(Start), End(End) {}
+ ExecutorAddrRange(ExecutorAddr Start, ExecutorAddrDiff Size)
+ : Start(Start), End(Start + Size) {}
- bool empty() const { return StartAddress == EndAddress; }
- ExecutorAddrDiff size() const { return EndAddress - StartAddress; }
+ bool empty() const { return Start == End; }
+ ExecutorAddrDiff size() const { return End - Start; }
+
+ friend bool operator==(const ExecutorAddrRange &LHS,
+ const ExecutorAddrRange &RHS) {
+ return LHS.Start == RHS.Start && LHS.End == RHS.End;
+ }
+ friend bool operator!=(const ExecutorAddrRange &LHS,
+ const ExecutorAddrRange &RHS) {
+ return !(LHS == RHS);
+ }
+ bool contains(ExecutorAddr Addr) const { return Start <= Addr && Addr < End; }
+ bool overlaps(const ExecutorAddrRange &Other) {
+ return !(Other.End <= Start || End <= Other.Start);
+ }
template <typename T> span<T> toSpan() const {
assert(size().getValue() % sizeof(T) == 0 &&
"AddressRange is not a multiple of sizeof(T)");
- return span<T>(StartAddress.toPtr<T *>(), size().getValue() / sizeof(T));
+ return span<T>(Start.toPtr<T *>(), size().getValue() / sizeof(T));
}
- ExecutorAddr StartAddress;
- ExecutorAddr EndAddress;
+ ExecutorAddr Start;
+ ExecutorAddr End;
};
/// SPS serializatior for ExecutorAddr.
class SPSSerializationTraits<SPSExecutorAddrRange, ExecutorAddrRange> {
public:
static size_t size(const ExecutorAddrRange &Value) {
- return SPSArgList<SPSExecutorAddr, SPSExecutorAddr>::size(
- Value.StartAddress, Value.EndAddress);
+ return SPSArgList<SPSExecutorAddr, SPSExecutorAddr>::size(Value.Start,
+ Value.End);
}
static bool serialize(SPSOutputBuffer &BOB, const ExecutorAddrRange &Value) {
return SPSArgList<SPSExecutorAddr, SPSExecutorAddr>::serialize(
- BOB, Value.StartAddress, Value.EndAddress);
+ BOB, Value.Start, Value.End);
}
static bool deserialize(SPSInputBuffer &BIB, ExecutorAddrRange &Value) {
return SPSArgList<SPSExecutorAddr, SPSExecutorAddr>::deserialize(
- BIB, Value.StartAddress, Value.EndAddress);
+ BIB, Value.Start, Value.End);
}
};
if (SE.size().getValue() % sizeof(uintptr_t)) {
std::ostringstream ErrMsg;
ErrMsg << std::hex << "Size of " << SectionName << " 0x"
- << SE.StartAddress.getValue() << " -- 0x" << SE.EndAddress.getValue()
+ << SE.Start.getValue() << " -- 0x" << SE.End.getValue()
<< " is not a pointer multiple";
return make_error<StringError>(ErrMsg.str());
}
return Err;
fprintf(stderr, "Processing selrefs section at 0x%llx\n",
- ObjCSelRefs.StartAddress.getValue());
+ ObjCSelRefs.Start.getValue());
for (uintptr_t SelEntry : ObjCSelRefs.toSpan<uintptr_t>()) {
const char *SelName = reinterpret_cast<const char *>(SelEntry);
fprintf(stderr, "Registering selector \"%s\"\n", SelName);
for (const auto &Swift5Protocols : Swift5ProtocolSections)
swift_registerProtocols(
- Swift5Protocols.StartAddress.toPtr<const ProtocolRecord *>(),
- Swift5Protocols.EndAddress.toPtr<const ProtocolRecord *>());
+ Swift5Protocols.Start.toPtr<const ProtocolRecord *>(),
+ Swift5Protocols.End.toPtr<const ProtocolRecord *>());
return Error::success();
}
for (const auto &ProtoConfSec : Swift5ProtocolConformanceSections)
swift_registerProtocolConformances(
- ProtoConfSec.StartAddress.toPtr<const ProtocolConformanceRecord *>(),
- ProtoConfSec.EndAddress.toPtr<const ProtocolConformanceRecord *>());
+ ProtoConfSec.Start.toPtr<const ProtocolConformanceRecord *>(),
+ ProtoConfSec.End.toPtr<const ProtocolConformanceRecord *>());
return Error::success();
}
Error MachOPlatformRuntimeState::registerObjectSections(
MachOPerObjectSectionsToRegister POSR) {
- if (POSR.EHFrameSection.StartAddress)
+ if (POSR.EHFrameSection.Start)
walkEHFrameSection(POSR.EHFrameSection.toSpan<const char>(),
__register_frame);
- if (POSR.ThreadDataSection.StartAddress) {
+ if (POSR.ThreadDataSection.Start) {
if (auto Err = registerThreadDataSection(
POSR.ThreadDataSection.toSpan<const char>()))
return Err;
Error MachOPlatformRuntimeState::deregisterObjectSections(
MachOPerObjectSectionsToRegister POSR) {
- if (POSR.EHFrameSection.StartAddress)
+ if (POSR.EHFrameSection.Start)
walkEHFrameSection(POSR.EHFrameSection.toSpan<const char>(),
__deregister_frame);
c_api_test.cpp
endian_test.cpp
error_test.cpp
+ executor_address_test.cpp
extensible_rtti_test.cpp
orc_unit_test_main.cpp
stl_extras_test.cpp
--- /dev/null
+//===-- extensible_address_test.cpp ---------------------------------------===//
+//
+// 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 is a part of the ORC runtime.
+//
+// Note:
+// This unit test was adapted from
+// llvm/unittests/Support/ExecutorAddressTest.cpp
+//
+//===----------------------------------------------------------------------===//
+
+#include "executor_address.h"
+#include "gtest/gtest.h"
+
+using namespace __orc_rt;
+
+TEST(ExecutorAddrTest, DefaultAndNull) {
+ // Check that default constructed values and isNull behave as expected.
+
+ ExecutorAddr Default;
+ ExecutorAddr Null(0);
+ ExecutorAddr NonNull(1);
+
+ EXPECT_TRUE(Null.isNull());
+ EXPECT_EQ(Default, Null);
+
+ EXPECT_FALSE(NonNull.isNull());
+ EXPECT_NE(Default, NonNull);
+}
+
+TEST(ExecutorAddrTest, Ordering) {
+ // Check that ordering operations.
+ ExecutorAddr A1(1), A2(2);
+
+ EXPECT_LE(A1, A1);
+ EXPECT_LT(A1, A2);
+ EXPECT_GT(A2, A1);
+ EXPECT_GE(A2, A2);
+}
+
+TEST(ExecutorAddrTest, PtrConversion) {
+ // Test toPtr / fromPtr round-tripping.
+ int X = 0;
+ auto XAddr = ExecutorAddr::fromPtr(&X);
+ int *XPtr = XAddr.toPtr<int *>();
+
+ EXPECT_EQ(XPtr, &X);
+}
+
+TEST(ExecutorAddrTest, AddrRanges) {
+ ExecutorAddr A0(0), A1(1), A2(2), A3(3);
+ ExecutorAddrRange R0(A0, A1), R1(A1, A2), R2(A2, A3), R3(A0, A2), R4(A1, A3);
+ // 012
+ // R0: # -- Before R1
+ // R1: # --
+ // R2: # -- After R1
+ // R3: ## -- Overlaps R1 start
+ // R4: ## -- Overlaps R1 end
+
+ EXPECT_EQ(R1, ExecutorAddrRange(A1, A2));
+ EXPECT_EQ(R1, ExecutorAddrRange(A1, ExecutorAddrDiff(1)));
+ EXPECT_NE(R1, R2);
+
+ EXPECT_TRUE(R1.contains(A1));
+ EXPECT_FALSE(R1.contains(A0));
+ EXPECT_FALSE(R1.contains(A2));
+
+ EXPECT_FALSE(R1.overlaps(R0));
+ EXPECT_FALSE(R1.overlaps(R2));
+ EXPECT_TRUE(R1.overlaps(R3));
+ EXPECT_TRUE(R1.overlaps(R4));
+}