summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/hle/kernel/kernel.cpp7
-rw-r--r--src/core/hle/kernel/object_address_table.cpp34
-rw-r--r--src/core/hle/kernel/object_address_table.h62
3 files changed, 101 insertions, 2 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 7470a97ca..b0c3f4ae1 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -6,6 +6,7 @@
#include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/memory.h"
+#include "core/hle/kernel/object_address_table.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/resource_limit.h"
#include "core/hle/kernel/thread.h"
@@ -35,7 +36,9 @@ void Init(u32 system_mode) {
/// Shutdown the kernel
void Shutdown() {
- g_handle_table.Clear(); // Free all kernel objects
+ // Free all kernel objects
+ g_handle_table.Clear();
+ g_object_address_table.Clear();
Kernel::ThreadingShutdown();
g_current_process = nullptr;
@@ -45,4 +48,4 @@ void Shutdown() {
Kernel::MemoryShutdown();
}
-} // namespace
+} // namespace Kernel
diff --git a/src/core/hle/kernel/object_address_table.cpp b/src/core/hle/kernel/object_address_table.cpp
new file mode 100644
index 000000000..dda532a88
--- /dev/null
+++ b/src/core/hle/kernel/object_address_table.cpp
@@ -0,0 +1,34 @@
+// Copyright 2018 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/assert.h"
+#include "core/hle/kernel/object_address_table.h"
+
+namespace Kernel {
+
+ObjectAddressTable g_object_address_table;
+
+void ObjectAddressTable::Insert(VAddr addr, SharedPtr<Object> obj) {
+ ASSERT_MSG(objects.find(addr) == objects.end(), "Object already exists with addr=0x%llx", addr);
+ objects[addr] = obj;
+}
+
+void ObjectAddressTable::Close(VAddr addr) {
+ ASSERT_MSG(objects.find(addr) != objects.end(), "Object does not exist with addr=0x%llx", addr);
+ objects.erase(addr);
+}
+
+SharedPtr<Object> ObjectAddressTable::GetGeneric(VAddr addr) const {
+ auto iter = objects.find(addr);
+ if (iter != objects.end()) {
+ return iter->second;
+ }
+ return {};
+}
+
+void ObjectAddressTable::Clear() {
+ objects.clear();
+}
+
+} // namespace Kernel
diff --git a/src/core/hle/kernel/object_address_table.h b/src/core/hle/kernel/object_address_table.h
new file mode 100644
index 000000000..ba0aac9e3
--- /dev/null
+++ b/src/core/hle/kernel/object_address_table.h
@@ -0,0 +1,62 @@
+// Copyright 2018 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <map>
+#include "common/common_types.h"
+#include "core/hle/kernel/kernel.h"
+
+namespace Kernel {
+
+/**
+ * This class is used to keep a table of Kernel objects and their respective addresses in emulated
+ * memory. For certain Switch SVCs, Kernel objects are referenced by an address to an object the
+ * guest application manages, so we use this table to look these kernel objects up. This is similiar
+ * to the HandleTable class.
+ */
+class ObjectAddressTable final : NonCopyable {
+public:
+ ObjectAddressTable() = default;
+
+ /**
+ * Inserts an object and address pair into the table.
+ */
+ void Insert(VAddr addr, SharedPtr<Object> obj);
+
+ /**
+ * Closes an object by its address, removing it from the table and decreasing the object's
+ * ref-count.
+ * @return `RESULT_SUCCESS` or one of the following errors:
+ * - `ERR_INVALID_HANDLE`: an invalid handle was passed in.
+ */
+ void Close(VAddr addr);
+
+ /**
+ * Looks up an object by its address.
+ * @return Pointer to the looked-up object, or `nullptr` if the handle is not valid.
+ */
+ SharedPtr<Object> GetGeneric(VAddr addr) const;
+
+ /**
+ * Looks up an object by its address while verifying its type.
+ * @return Pointer to the looked-up object, or `nullptr` if the handle is not valid or its
+ * type differs from the requested one.
+ */
+ template <class T>
+ SharedPtr<T> Get(VAddr addr) const {
+ return DynamicObjectCast<T>(GetGeneric(addr));
+ }
+
+ /// Closes all addresses held in this table.
+ void Clear();
+
+private:
+ /// Stores the Object referenced by the address
+ std::map<VAddr, SharedPtr<Object>> objects;
+};
+
+extern ObjectAddressTable g_object_address_table;
+
+} // namespace Kernel