mirror of
https://github.com/dart-lang/sdk
synced 2024-10-06 16:00:45 +00:00
4ce23629eb
This can be controlled via codesigning_identity GN arg. For example, setting codesigning_identity="-" would produce ad-hoc signed binaries. This CL also includes changes in vm/cc tests which are needed for tests to be green when running with hardened runtime. Issue https://github.com/dart-lang/sdk/issues/53928 Tested: enabled ad-hoc signing and tested on bots. Cq-Include-Trybots: luci.dart.try:vm-mac-debug-arm64-try,vm-mac-release-arm64-try,vm-mac-release-x64-try,vm-mac-debug-x64-try Change-Id: I3c3a6265c62b2904e43a326b7d8223bcfd393577 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/333401 Reviewed-by: Ryan Macnak <rmacnak@google.com> Commit-Queue: Slava Egorov <vegorov@google.com>
140 lines
4.5 KiB
C++
140 lines
4.5 KiB
C++
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
#include "vm/virtual_memory.h"
|
|
#include "platform/assert.h"
|
|
#include "vm/heap/heap.h"
|
|
#include "vm/unit_test.h"
|
|
#include "vm/virtual_memory_compressed.h"
|
|
|
|
namespace dart {
|
|
|
|
bool IsZero(char* begin, char* end) {
|
|
for (char* current = begin; current < end; ++current) {
|
|
if (*current != 0) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
VM_UNIT_TEST_CASE(AllocateVirtualMemory) {
|
|
const intptr_t kVirtualMemoryBlockSize = 64 * KB;
|
|
VirtualMemory* vm =
|
|
VirtualMemory::Allocate(kVirtualMemoryBlockSize, false, false, "test");
|
|
EXPECT(vm != nullptr);
|
|
EXPECT(vm->address() != nullptr);
|
|
EXPECT_EQ(vm->start(), reinterpret_cast<uword>(vm->address()));
|
|
EXPECT_EQ(kVirtualMemoryBlockSize, vm->size());
|
|
EXPECT_EQ(vm->start() + kVirtualMemoryBlockSize, vm->end());
|
|
EXPECT(vm->Contains(vm->start()));
|
|
EXPECT(vm->Contains(vm->start() + 1));
|
|
EXPECT(vm->Contains(vm->start() + kVirtualMemoryBlockSize - 1));
|
|
EXPECT(vm->Contains(vm->start() + (kVirtualMemoryBlockSize / 2)));
|
|
EXPECT(!vm->Contains(vm->start() - 1));
|
|
EXPECT(!vm->Contains(vm->end()));
|
|
EXPECT(!vm->Contains(vm->end() + 1));
|
|
EXPECT(!vm->Contains(0));
|
|
EXPECT(!vm->Contains(static_cast<uword>(-1)));
|
|
|
|
char* buf = reinterpret_cast<char*>(vm->address());
|
|
EXPECT(IsZero(buf, buf + vm->size()));
|
|
buf[0] = 'a';
|
|
buf[1] = 'c';
|
|
buf[2] = '/';
|
|
buf[3] = 'd';
|
|
buf[4] = 'c';
|
|
buf[5] = 0;
|
|
EXPECT_STREQ("ac/dc", buf);
|
|
|
|
delete vm;
|
|
}
|
|
|
|
VM_UNIT_TEST_CASE(AllocateAlignedVirtualMemory) {
|
|
intptr_t kHeapPageSize = kPageSize;
|
|
intptr_t kVirtualPageSize = 4096;
|
|
|
|
intptr_t kIterations = kHeapPageSize / kVirtualPageSize;
|
|
for (intptr_t i = 0; i < kIterations; i++) {
|
|
VirtualMemory* vm = VirtualMemory::AllocateAligned(
|
|
kHeapPageSize, kHeapPageSize, false, false, "test");
|
|
EXPECT(Utils::IsAligned(vm->start(), kHeapPageSize));
|
|
EXPECT_EQ(kHeapPageSize, vm->size());
|
|
delete vm;
|
|
}
|
|
}
|
|
|
|
VM_UNIT_TEST_CASE(FreeVirtualMemory) {
|
|
// Reservations should always be handed back to OS upon destruction.
|
|
const intptr_t kVirtualMemoryBlockSize = 10 * MB;
|
|
const intptr_t kIterations = 900; // Enough to exhaust 32-bit address space.
|
|
for (intptr_t i = 0; i < kIterations; ++i) {
|
|
VirtualMemory* vm =
|
|
VirtualMemory::Allocate(kVirtualMemoryBlockSize, false, false, "test");
|
|
delete vm;
|
|
}
|
|
// Check that truncation does not introduce leaks.
|
|
for (intptr_t i = 0; i < kIterations; ++i) {
|
|
VirtualMemory* vm =
|
|
VirtualMemory::Allocate(kVirtualMemoryBlockSize, false, false, "test");
|
|
vm->Truncate(kVirtualMemoryBlockSize / 2);
|
|
delete vm;
|
|
}
|
|
for (intptr_t i = 0; i < kIterations; ++i) {
|
|
VirtualMemory* vm =
|
|
VirtualMemory::Allocate(kVirtualMemoryBlockSize, true, false, "test");
|
|
vm->Truncate(0);
|
|
delete vm;
|
|
}
|
|
}
|
|
|
|
#if !defined(DART_TARGET_OS_FUCHSIA)
|
|
// TODO(https://dartbug.com/52579): Reenable on Fuchsia.
|
|
|
|
static int testFunction(int x) {
|
|
return x * 2;
|
|
}
|
|
|
|
NO_SANITIZE_UNDEFINED("function") // See https://dartbug.com/52440
|
|
VM_UNIT_TEST_CASE(DuplicateRXVirtualMemory) {
|
|
const uword page_size = VirtualMemory::PageSize();
|
|
const uword pointer = reinterpret_cast<uword>(&testFunction);
|
|
const uword page_start = Utils::RoundDown(pointer, page_size);
|
|
const uword offset = pointer - page_start;
|
|
|
|
// Grab 2 * page_size, in case testFunction happens to land near the end of
|
|
// the page.
|
|
VirtualMemory* vm = VirtualMemory::ForImagePage(
|
|
reinterpret_cast<void*>(page_start), 2 * page_size);
|
|
EXPECT_NE(nullptr, vm);
|
|
|
|
#if defined(DART_HOST_OS_MACOS) && !defined(DART_PRECOMPILED_RUNTIME)
|
|
// If we are not going to use vm_remap then we need to pass
|
|
// is_executable=true so that pages get allocated with MAP_JIT flag if
|
|
// necessary. Otherwise OS will kill us with a codesigning violation if
|
|
// hardened runtime is enabled.
|
|
const bool is_executable = true;
|
|
#else
|
|
const bool is_executable = false;
|
|
#endif
|
|
|
|
VirtualMemory* vm2 = VirtualMemory::AllocateAligned(
|
|
vm->size(), kPageSize, is_executable,
|
|
/*is_compressed=*/false, "FfiCallbackMetadata::TrampolinePage");
|
|
bool ok = vm->DuplicateRX(vm2);
|
|
EXPECT_EQ(true, ok);
|
|
|
|
auto testFunction2 = reinterpret_cast<int (*)(int)>(vm2->start() + offset);
|
|
EXPECT_NE(&testFunction, testFunction2);
|
|
|
|
EXPECT_EQ(246, testFunction2(123));
|
|
|
|
delete vm;
|
|
delete vm2;
|
|
}
|
|
|
|
#endif // !defined(DART_TARGET_OS_FUCHSIA)
|
|
|
|
} // namespace dart
|