Make fmt::ptr implicit for raw pointers + Update Submodules

This commit is contained in:
◱ PixelyIon 2020-10-05 14:49:23 +05:30 committed by ◱ PixelyIon
parent 02f3e37c4f
commit 878cb24389
10 changed files with 60 additions and 44 deletions

View File

@ -68,6 +68,22 @@ namespace skyline {
constexpr u64 NsInSecond{1000000000}; //!< The amount of nanoseconds in a second
}
namespace util {
/**
* @brief A way to implicitly cast all typed pointers to void pointers, this is used for libfmt as it requires wrapping non-void pointers with fmt::ptr
* @note This does not cover std::shared_ptr or std::unique_ptr and those will have to be explicitly passed through fmt::ptr
*/
template <class T>
constexpr T VoidCast(T item) {
return item;
}
template <class T>
constexpr const void* VoidCast(T* ptr) {
return ptr;
}
}
/**
* @brief A wrapper over std::runtime_error with libfmt formatting
*/
@ -78,7 +94,7 @@ namespace skyline {
* @param args The arguments based on format_str
*/
template<typename S, typename... Args>
inline exception(const S &formatStr, Args &&... args) : runtime_error(fmt::format(formatStr, args...)) {}
inline exception(const S &formatStr, Args &&... args) : runtime_error(fmt::format(formatStr, util::VoidCast(args)...)) {}
};
namespace util {
@ -188,7 +204,7 @@ namespace skyline {
return digit - 'a' + 10;
else if (digit >= 'A' && digit <= 'F')
return digit - 'A' + 10;
throw exception(fmt::format("Invalid hex char {}", digit));
throw exception("Invalid hex character: '{}'", digit);
}
template<size_t Size>
@ -428,7 +444,7 @@ namespace skyline {
template<typename S, typename... Args>
inline void Error(const S &formatStr, Args &&... args) {
if (LogLevel::Error <= configLevel) {
Write(LogLevel::Error, fmt::format(formatStr, args...));
Write(LogLevel::Error, fmt::format(formatStr, util::VoidCast(args)...));
}
}
@ -440,7 +456,7 @@ namespace skyline {
template<typename S, typename... Args>
inline void Warn(const S &formatStr, Args &&... args) {
if (LogLevel::Warn <= configLevel) {
Write(LogLevel::Warn, fmt::format(formatStr, args...));
Write(LogLevel::Warn, fmt::format(formatStr, util::VoidCast(args)...));
}
}
@ -452,7 +468,7 @@ namespace skyline {
template<typename S, typename... Args>
inline void Info(const S &formatStr, Args &&... args) {
if (LogLevel::Info <= configLevel) {
Write(LogLevel::Info, fmt::format(formatStr, args...));
Write(LogLevel::Info, fmt::format(formatStr, util::VoidCast(args)...));
}
}
@ -464,7 +480,7 @@ namespace skyline {
template<typename S, typename... Args>
inline void Debug(const S &formatStr, Args &&... args) {
if (LogLevel::Debug <= configLevel) {
Write(LogLevel::Debug, fmt::format(formatStr, args...));
Write(LogLevel::Debug, fmt::format(formatStr, util::VoidCast(args)...));
}
}
};

View File

@ -103,14 +103,14 @@ namespace skyline::kernel::ipc {
auto bufC{reinterpret_cast<BufferDescriptorC *>(pointer)};
if (bufC->address) {
outputBuf.emplace_back(bufC->Pointer(), u16(bufC->size));
state.logger->Debug("Buf C: AD: 0x{:X} SZ: 0x{:X}", fmt::ptr(bufC->Pointer()), u16(bufC->size));
state.logger->Debug("Buf C: AD: 0x{:X} SZ: 0x{:X}", bufC->Pointer(), u16(bufC->size));
}
} else if (header->cFlag > BufferCFlag::SingleDescriptor) {
for (u8 index{}; (static_cast<u8>(header->cFlag) - 2) > index; index++) { // (cFlag - 2) C descriptors are present
auto bufC{reinterpret_cast<BufferDescriptorC *>(pointer)};
if (bufC->address) {
outputBuf.emplace_back(bufC->Pointer(), u16(bufC->size));
state.logger->Debug("Buf C #{} AD: 0x{:X} SZ: 0x{:X}", index, fmt::ptr(bufC->Pointer()), u16(bufC->size));
state.logger->Debug("Buf C #{} AD: 0x{:X} SZ: 0x{:X}", index, bufC->Pointer(), u16(bufC->size));
}
pointer += sizeof(BufferDescriptorC);
}

View File

@ -67,7 +67,7 @@ namespace skyline::kernel {
auto upper{std::upper_bound(chunks.begin(), chunks.end(), chunk.ptr, [](const u8 *ptr, const ChunkDescriptor &chunk) -> bool { return ptr < chunk.ptr; })};
if (upper == chunks.begin())
throw exception("InsertChunk: Chunk inserted outside address space: 0x{:X} - 0x{:X} and 0x{:X} - 0x{:X}", fmt::ptr(upper->ptr), fmt::ptr(upper->ptr + upper->size), chunk.ptr, fmt::ptr(chunk.ptr + chunk.size));
throw exception("InsertChunk: Chunk inserted outside address space: 0x{:X} - 0x{:X} and 0x{:X} - 0x{:X}", upper->ptr, fmt::ptr(upper->ptr + upper->size), chunk.ptr, fmt::ptr(chunk.ptr + chunk.size));
upper = chunks.erase(upper, std::upper_bound(upper, chunks.end(), chunk.ptr + chunk.size, [](const u8 *ptr, const ChunkDescriptor &chunk) -> bool { return ptr < chunk.ptr; }));
if (upper != chunks.end() && upper->ptr < chunk.ptr + chunk.size) {

View File

@ -24,14 +24,14 @@ namespace skyline::kernel::svc {
state.ctx->registers.w0 = Result{};
state.ctx->registers.x1 = reinterpret_cast<u64>(heap->ptr);
state.logger->Debug("svcSetHeapSize: Allocated at 0x{:X} for 0x{:X} bytes", fmt::ptr(heap->ptr), heap->size);
state.logger->Debug("svcSetHeapSize: Allocated at 0x{:X} for 0x{:X} bytes", heap->ptr, heap->size);
}
void SetMemoryAttribute(DeviceState &state) {
auto pointer{reinterpret_cast<u8 *>(state.ctx->registers.x0)};
if (!util::PageAligned(pointer)) {
state.ctx->registers.w0 = result::InvalidAddress;
state.logger->Warn("svcSetMemoryAttribute: 'pointer' not page aligned: 0x{:X}", fmt::ptr(pointer));
state.logger->Warn("svcSetMemoryAttribute: 'pointer' not page aligned: 0x{:X}", pointer);
return;
}
@ -55,13 +55,13 @@ namespace skyline::kernel::svc {
auto chunk{state.os->memory.Get(pointer)};
if (!chunk) {
state.ctx->registers.w0 = result::InvalidAddress;
state.logger->Warn("svcSetMemoryAttribute: Cannot find memory region: 0x{:X}", fmt::ptr(pointer));
state.logger->Warn("svcSetMemoryAttribute: Cannot find memory region: 0x{:X}", pointer);
return;
}
if (!chunk->state.attributeChangeAllowed) {
state.ctx->registers.w0 = result::InvalidState;
state.logger->Warn("svcSetMemoryAttribute: Attribute change not allowed for chunk: 0x{:X}", fmt::ptr(pointer));
state.logger->Warn("svcSetMemoryAttribute: Attribute change not allowed for chunk: 0x{:X}", pointer);
return;
}
@ -71,7 +71,7 @@ namespace skyline::kernel::svc {
newChunk.attributes.isUncached = value.isUncached;
state.os->memory.InsertChunk(newChunk);
state.logger->Debug("svcSetMemoryAttribute: Set caching to {} at 0x{:X} for 0x{:X} bytes", bool(value.isUncached), fmt::ptr(pointer), size);
state.logger->Debug("svcSetMemoryAttribute: Set caching to {} at 0x{:X} for 0x{:X} bytes", bool(value.isUncached), pointer, size);
state.ctx->registers.w0 = Result{};
}
@ -82,7 +82,7 @@ namespace skyline::kernel::svc {
if (!util::PageAligned(destination) || !util::PageAligned(source)) {
state.ctx->registers.w0 = result::InvalidAddress;
state.logger->Warn("svcMapMemory: Addresses not page aligned: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", fmt::ptr(source), fmt::ptr(destination), size);
state.logger->Warn("svcMapMemory: Addresses not page aligned: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
return;
}
@ -95,19 +95,19 @@ namespace skyline::kernel::svc {
auto stack{state.os->memory.stack};
if (!stack.IsInside(destination)) {
state.ctx->registers.w0 = result::InvalidMemoryRegion;
state.logger->Warn("svcMapMemory: Destination not within stack region: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", fmt::ptr(source), fmt::ptr(destination), size);
state.logger->Warn("svcMapMemory: Destination not within stack region: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
return;
}
auto chunk{state.os->memory.Get(source)};
if (!chunk) {
state.ctx->registers.w0 = result::InvalidAddress;
state.logger->Warn("svcMapMemory: Source has no descriptor: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", fmt::ptr(source), fmt::ptr(destination), size);
state.logger->Warn("svcMapMemory: Source has no descriptor: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
return;
}
if (!chunk->state.mapAllowed) {
state.ctx->registers.w0 = result::InvalidState;
state.logger->Warn("svcMapMemory: Source doesn't allow usage of svcMapMemory: Source: 0x{:X}, Destination: 0x{:X}, Size: 0x{:X}, MemoryState: 0x{:X}", fmt::ptr(source), fmt::ptr(destination), size, chunk->state.value);
state.logger->Warn("svcMapMemory: Source doesn't allow usage of svcMapMemory: Source: 0x{:X}, Destination: 0x{:X}, Size: 0x{:X}, MemoryState: 0x{:X}", source, destination, size, chunk->state.value);
return;
}
@ -116,10 +116,10 @@ namespace skyline::kernel::svc {
auto object{state.process->GetMemoryObject(source)};
if (!object)
throw exception("svcMapMemory: Cannot find memory object in handle table for address 0x{:X}", fmt::ptr(source));
throw exception("svcMapMemory: Cannot find memory object in handle table for address 0x{:X}", source);
object->item->UpdatePermission(source, size, {false, false, false});
state.logger->Debug("svcMapMemory: Mapped range 0x{:X} - 0x{:X} to 0x{:X} - 0x{:X} (Size: 0x{:X} bytes)", fmt::ptr(source), fmt::ptr(source + size), fmt::ptr(destination), fmt::ptr(destination + size), size);
state.logger->Debug("svcMapMemory: Mapped range 0x{:X} - 0x{:X} to 0x{:X} - 0x{:X} (Size: 0x{:X} bytes)", source, fmt::ptr(source + size), destination, fmt::ptr(destination + size), size);
state.ctx->registers.w0 = Result{};
}
@ -206,7 +206,7 @@ namespace skyline::kernel::svc {
.type = static_cast<u32>(memory::MemoryType::Reserved),
};
state.logger->Debug("svcQueryMemory: Trying to query memory outside of the application's address space: 0x{:X}", fmt::ptr(pointer));
state.logger->Debug("svcQueryMemory: Trying to query memory outside of the application's address space: 0x{:X}", pointer);
}
*reinterpret_cast<memory::MemoryInfo*>(state.ctx->registers.x0) = memInfo;
@ -368,7 +368,7 @@ namespace skyline::kernel::svc {
}
auto tmem{state.process->NewHandle<type::KTransferMemory>(pointer, size, permission)};
state.logger->Debug("svcCreateTransferMemory: Creating transfer memory at 0x{:X} for {} bytes ({}{}{})", fmt::ptr(pointer), size, permission.r ? 'R' : '-', permission.w ? 'W' : '-', permission.x ? 'X' : '-');
state.logger->Debug("svcCreateTransferMemory: Creating transfer memory at 0x{:X} for {} bytes ({}{}{})", pointer, size, permission.r ? 'R' : '-', permission.w ? 'W' : '-', permission.x ? 'X' : '-');
state.ctx->registers.w0 = Result{};
state.ctx->registers.w1 = tmem.handle;
@ -490,7 +490,7 @@ namespace skyline::kernel::svc {
void ArbitrateLock(DeviceState &state) {
auto pointer{reinterpret_cast<u32*>(state.ctx->registers.x1)};
if (!util::WordAligned(pointer)) {
state.logger->Warn("svcArbitrateLock: 'pointer' not word aligned: 0x{:X}", fmt::ptr(pointer));
state.logger->Warn("svcArbitrateLock: 'pointer' not word aligned: 0x{:X}", pointer);
state.ctx->registers.w0 = result::InvalidAddress;
return;
}
@ -500,12 +500,12 @@ namespace skyline::kernel::svc {
if (requesterHandle != state.thread->handle)
throw exception("svcWaitProcessWideKeyAtomic: Handle doesn't match current thread: 0x{:X} for thread 0x{:X}", requesterHandle, state.thread->handle);
state.logger->Debug("svcArbitrateLock: Locking mutex at 0x{:X}", fmt::ptr(pointer));
state.logger->Debug("svcArbitrateLock: Locking mutex at 0x{:X}", pointer);
if (state.process->MutexLock(pointer, ownerHandle))
state.logger->Debug("svcArbitrateLock: Locked mutex at 0x{:X}", fmt::ptr(pointer));
state.logger->Debug("svcArbitrateLock: Locked mutex at 0x{:X}", pointer);
else
state.logger->Debug("svcArbitrateLock: Owner handle did not match current owner for mutex or didn't have waiter flag at 0x{:X}", fmt::ptr(pointer));
state.logger->Debug("svcArbitrateLock: Owner handle did not match current owner for mutex or didn't have waiter flag at 0x{:X}", pointer);
state.ctx->registers.w0 = Result{};
}
@ -513,18 +513,18 @@ namespace skyline::kernel::svc {
void ArbitrateUnlock(DeviceState &state) {
auto mutex{reinterpret_cast<u32*>(state.ctx->registers.x0)};
if (!util::WordAligned(mutex)) {
state.logger->Warn("svcArbitrateUnlock: mutex pointer not word aligned: 0x{:X}", fmt::ptr(mutex));
state.logger->Warn("svcArbitrateUnlock: mutex pointer not word aligned: 0x{:X}", mutex);
state.ctx->registers.w0 = result::InvalidAddress;
return;
}
state.logger->Debug("svcArbitrateUnlock: Unlocking mutex at 0x{:X}", fmt::ptr(mutex));
state.logger->Debug("svcArbitrateUnlock: Unlocking mutex at 0x{:X}", mutex);
if (state.process->MutexUnlock(mutex)) {
state.logger->Debug("svcArbitrateUnlock: Unlocked mutex at 0x{:X}", fmt::ptr(mutex));
state.logger->Debug("svcArbitrateUnlock: Unlocked mutex at 0x{:X}", mutex);
state.ctx->registers.w0 = Result{};
} else {
state.logger->Debug("svcArbitrateUnlock: A non-owner thread tried to release a mutex at 0x{:X}", fmt::ptr(mutex));
state.logger->Debug("svcArbitrateUnlock: A non-owner thread tried to release a mutex at 0x{:X}", mutex);
state.ctx->registers.w0 = result::InvalidAddress;
}
}
@ -532,7 +532,7 @@ namespace skyline::kernel::svc {
void WaitProcessWideKeyAtomic(DeviceState &state) {
auto mutex{reinterpret_cast<u32*>(state.ctx->registers.x0)};
if (!util::WordAligned(mutex)) {
state.logger->Warn("svcWaitProcessWideKeyAtomic: mutex pointer not word aligned: 0x{:X}", fmt::ptr(mutex));
state.logger->Warn("svcWaitProcessWideKeyAtomic: mutex pointer not word aligned: 0x{:X}", mutex);
state.ctx->registers.w0 = result::InvalidAddress;
return;
}
@ -543,13 +543,13 @@ namespace skyline::kernel::svc {
throw exception("svcWaitProcessWideKeyAtomic: Handle doesn't match current thread: 0x{:X} for thread 0x{:X}", handle, state.thread->handle);
if (!state.process->MutexUnlock(mutex)) {
state.logger->Debug("WaitProcessWideKeyAtomic: A non-owner thread tried to release a mutex at 0x{:X}", fmt::ptr(mutex));
state.logger->Debug("WaitProcessWideKeyAtomic: A non-owner thread tried to release a mutex at 0x{:X}", mutex);
state.ctx->registers.w0 = result::InvalidAddress;
return;
}
auto timeout{state.ctx->registers.x3};
state.logger->Debug("svcWaitProcessWideKeyAtomic: Mutex: 0x{:X}, Conditional-Variable: 0x{:X}, Timeout: {} ns", fmt::ptr(mutex), conditional, timeout);
state.logger->Debug("svcWaitProcessWideKeyAtomic: Mutex: 0x{:X}, Conditional-Variable: 0x{:X}, Timeout: {} ns", mutex, conditional, timeout);
if (state.process->ConditionalVariableWait(conditional, mutex, timeout)) {
state.logger->Debug("svcWaitProcessWideKeyAtomic: Waited for conditional variable and relocked mutex");

View File

@ -12,7 +12,7 @@
namespace skyline::kernel::type {
KPrivateMemory::KPrivateMemory(const DeviceState &state, u8* ptr, size_t size, memory::Permission permission, memory::MemoryState memState) : size(size), permission(permission), memState(memState), KMemory(state, KType::KPrivateMemory) {
if (ptr && !util::PageAligned(ptr))
throw exception("KPrivateMemory was created with non-page-aligned address: 0x{:X}", fmt::ptr(ptr));
throw exception("KPrivateMemory was created with non-page-aligned address: 0x{:X}", ptr);
ptr = reinterpret_cast<u8*>(mmap(ptr, size, PROT_READ | PROT_WRITE | PROT_EXEC, ptr ? MAP_FIXED : 0, 0, 0));
if (ptr == MAP_FAILED)
@ -53,7 +53,7 @@ namespace skyline::kernel::type {
void KPrivateMemory::UpdatePermission(u8* ptr, size_t size, memory::Permission permission) {
if (ptr && !util::PageAligned(ptr))
throw exception("KPrivateMemory permission updated with a non-page-aligned address: 0x{:X}", fmt::ptr(ptr));
throw exception("KPrivateMemory permission updated with a non-page-aligned address: 0x{:X}", ptr);
// If a static code region has been mapped as writable it needs to be changed to mutable
if (memState.value == memory::states::CodeStatic.value && permission.w)

View File

@ -24,7 +24,7 @@ namespace skyline::kernel::type {
u8 *KSharedMemory::Map(u8 *ptr, u64 size, memory::Permission permission) {
if (ptr && !util::PageAligned(ptr))
throw exception("KSharedMemory was mapped to a non-page-aligned address: 0x{:X}", fmt::ptr(ptr));
throw exception("KSharedMemory was mapped to a non-page-aligned address: 0x{:X}", ptr);
guest.ptr = reinterpret_cast<u8*>(mmap(ptr, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | (ptr ? MAP_FIXED : 0), fd, 0));
if (guest.ptr == MAP_FAILED)
@ -43,7 +43,7 @@ namespace skyline::kernel::type {
void KSharedMemory::UpdatePermission(u8* ptr, size_t size, memory::Permission permission) {
if (ptr && !util::PageAligned(ptr))
throw exception("KSharedMemory permission updated with a non-page-aligned address: 0x{:X}", fmt::ptr(ptr));
throw exception("KSharedMemory permission updated with a non-page-aligned address: 0x{:X}", ptr);
if (guest.Valid()) {
mprotect(ptr, size, permission.Get());

View File

@ -25,7 +25,7 @@ namespace skyline::loader {
u64 offset{loadInfo.size};
u8* base{loadInfo.base};
state.logger->Info("Loaded nso 'rtld' at 0x{:X}", fmt::ptr(base));
state.logger->Info("Loaded nso 'rtld' at 0x{:X}", base);
for (const auto &nso : {"main", "subsdk0", "subsdk1", "subsdk2", "subsdk3", "subsdk4", "subsdk5", "subsdk6", "subsdk7", "sdk"}) {
nsoFile = exeFs->OpenFile(nso);

View File

@ -40,7 +40,7 @@ namespace skyline::service::audio {
} &data{request.inputBuf.at(0).as<Data>()};
auto tag{request.Pop<u64>()};
state.logger->Debug("Appending buffer with address: 0x{:X}, size: 0x{:X}", fmt::ptr(data.sampleBuffer), data.sampleSize);
state.logger->Debug("Appending buffer with address: 0x{:X}, size: 0x{:X}", data.sampleBuffer, data.sampleSize);
span samples(data.sampleBuffer, data.sampleSize / sizeof(i16));
if (sampleRate != constant::SampleRate) {

View File

@ -44,7 +44,7 @@ namespace skyline::service::nvdrv {
else
buffer = request.outputBuf[0];
} else {
throw exception("IOCTL Input Buffer (0x{:X}) != Output Buffer (0x{:X})", fmt::ptr(request.inputBuf[0].data()), fmt::ptr(request.outputBuf[0].data()));
throw exception("IOCTL Input Buffer (0x{:X}) != Output Buffer (0x{:X})", request.inputBuf[0].data(), request.outputBuf[0].data());
}
response.Push(device->HandleIoctl(cmd, device::IoctlType::Ioctl, buffer, {}));
@ -104,7 +104,7 @@ namespace skyline::service::nvdrv {
if (request.inputBuf.size() < 2 || request.outputBuf.empty())
throw exception("Inadequate amount of buffers for IOCTL2: I - {}, O - {}", request.inputBuf.size(), request.outputBuf.size());
else if (request.inputBuf[0].data() != request.outputBuf[0].data())
throw exception("IOCTL2 Input Buffer (0x{:X}) != Output Buffer (0x{:X}) [Input Buffer #2: 0x{:X}]", fmt::ptr(request.inputBuf[0].data()), fmt::ptr(request.outputBuf[0].data()), fmt::ptr(request.inputBuf[1].data()));
throw exception("IOCTL2 Input Buffer (0x{:X}) != Output Buffer (0x{:X}) [Input Buffer #2: 0x{:X}]", request.inputBuf[0].data(), request.outputBuf[0].data(), request.inputBuf[1].data());
span<u8> buffer{};
if (request.inputBuf[0].size() >= request.outputBuf[0].size())
@ -128,7 +128,7 @@ namespace skyline::service::nvdrv {
if (request.inputBuf.empty() || request.outputBuf.size() < 2)
throw exception("Inadequate amount of buffers for IOCTL3: I - {}, O - {}", request.inputBuf.size(), request.outputBuf.size());
else if (request.inputBuf[0].data() != request.outputBuf[0].data())
throw exception("IOCTL3 Input Buffer (0x{:X}) != Output Buffer (0x{:X}) [Output Buffer #2: 0x{:X}]", fmt::ptr(request.inputBuf[0].data()), fmt::ptr(request.outputBuf[0].data()), fmt::ptr(request.outputBuf[1].data()));
throw exception("IOCTL3 Input Buffer (0x{:X}) != Output Buffer (0x{:X}) [Output Buffer #2: 0x{:X}]", request.inputBuf[0].data(), request.outputBuf[0].data(), request.outputBuf[1].data());
span<u8> buffer{};
if (request.inputBuf[0].size() >= request.outputBuf[0].size())

View File

@ -59,7 +59,7 @@ namespace skyline::service::nvdrv::device {
object->pointer = data.pointer;
object->status = NvMapObject::Status::Allocated;
state.logger->Debug("Handle: 0x{:X}, HeapMask: 0x{:X}, Flags: {}, Align: 0x{:X}, Kind: {}, Address: 0x{:X}", data.handle, data.heapMask, data.flags, data.align, data.kind, fmt::ptr(data.pointer));
state.logger->Debug("Handle: 0x{:X}, HeapMask: 0x{:X}, Flags: {}, Align: 0x{:X}, Kind: {}, Address: 0x{:X}", data.handle, data.heapMask, data.flags, data.align, data.kind, data.pointer);
return NvStatus::Success;
} catch (const std::out_of_range &) {
state.logger->Warn("Invalid NvMap handle: 0x{:X}", data.handle);
@ -89,7 +89,7 @@ namespace skyline::service::nvdrv::device {
data.size = object->size;
handleTable.erase(data.handle);
state.logger->Debug("Handle: 0x{:X} -> Address: 0x{:X}, Size: 0x{:X}, Flags: 0x{:X}", data.handle, fmt::ptr(data.pointer), data.size, data.flags);
state.logger->Debug("Handle: 0x{:X} -> Address: 0x{:X}, Size: 0x{:X}, Flags: 0x{:X}", data.handle, data.pointer, data.size, data.flags);
return NvStatus::Success;
} catch (const std::out_of_range &) {
state.logger->Warn("Invalid NvMap handle: 0x{:X}", data.handle);