summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Lioncash2018-12-03 22:50:16 -0500
committerGravatar Lioncash2018-12-04 02:20:47 -0500
commit5eb057f422ac316cd1b943f6cd00aabc673dc238 (patch)
tree837d0d14341f50cda47b73d5128104980eb1afbc /src
parentMerge pull request #1852 from VPeruS/fix-format-string (diff)
downloadyuzu-5eb057f422ac316cd1b943f6cd00aabc673dc238.tar.gz
yuzu-5eb057f422ac316cd1b943f6cd00aabc673dc238.tar.xz
yuzu-5eb057f422ac316cd1b943f6cd00aabc673dc238.zip
kernel/object: Amend handle types to distinguish between readable and writable events
Two kernel object should absolutely never have the same handle ID type. This can cause incorrect behavior when it comes to retrieving object types from the handle table. In this case it allows converting a WritableEvent into a ReadableEvent and vice-versa, which is undefined behavior, since the object types are not the same. This also corrects ClearEvent() to check both kernel types like the kernel itself does.
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/object.cpp3
-rw-r--r--src/core/hle/kernel/object.h3
-rw-r--r--src/core/hle/kernel/readable_event.h2
-rw-r--r--src/core/hle/kernel/svc.cpp19
-rw-r--r--src/core/hle/kernel/writable_event.h2
-rw-r--r--src/yuzu/debugger/wait_tree.cpp2
6 files changed, 20 insertions, 11 deletions
diff --git a/src/core/hle/kernel/object.cpp b/src/core/hle/kernel/object.cpp
index d87a62bb9..bb1b68778 100644
--- a/src/core/hle/kernel/object.cpp
+++ b/src/core/hle/kernel/object.cpp
@@ -13,7 +13,7 @@ Object::~Object() = default;
13 13
14bool Object::IsWaitable() const { 14bool Object::IsWaitable() const {
15 switch (GetHandleType()) { 15 switch (GetHandleType()) {
16 case HandleType::Event: 16 case HandleType::ReadableEvent:
17 case HandleType::Thread: 17 case HandleType::Thread:
18 case HandleType::Timer: 18 case HandleType::Timer:
19 case HandleType::ServerPort: 19 case HandleType::ServerPort:
@@ -21,6 +21,7 @@ bool Object::IsWaitable() const {
21 return true; 21 return true;
22 22
23 case HandleType::Unknown: 23 case HandleType::Unknown:
24 case HandleType::WritableEvent:
24 case HandleType::SharedMemory: 25 case HandleType::SharedMemory:
25 case HandleType::Process: 26 case HandleType::Process:
26 case HandleType::AddressArbiter: 27 case HandleType::AddressArbiter:
diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h
index 69082ce3e..f1606a204 100644
--- a/src/core/hle/kernel/object.h
+++ b/src/core/hle/kernel/object.h
@@ -19,7 +19,8 @@ using Handle = u32;
19 19
20enum class HandleType : u32 { 20enum class HandleType : u32 {
21 Unknown, 21 Unknown,
22 Event, 22 WritableEvent,
23 ReadableEvent,
23 SharedMemory, 24 SharedMemory,
24 Thread, 25 Thread,
25 Process, 26 Process,
diff --git a/src/core/hle/kernel/readable_event.h b/src/core/hle/kernel/readable_event.h
index b1f1f4871..867ff3051 100644
--- a/src/core/hle/kernel/readable_event.h
+++ b/src/core/hle/kernel/readable_event.h
@@ -29,7 +29,7 @@ public:
29 return reset_type; 29 return reset_type;
30 } 30 }
31 31
32 static const HandleType HANDLE_TYPE = HandleType::Event; 32 static const HandleType HANDLE_TYPE = HandleType::ReadableEvent;
33 HandleType GetHandleType() const override { 33 HandleType GetHandleType() const override {
34 return HANDLE_TYPE; 34 return HANDLE_TYPE;
35 } 35 }
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 948989b31..d2d893992 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -1575,14 +1575,21 @@ static ResultCode ClearEvent(Handle handle) {
1575 LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle); 1575 LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle);
1576 1576
1577 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 1577 const auto& handle_table = Core::CurrentProcess()->GetHandleTable();
1578 SharedPtr<ReadableEvent> evt = handle_table.Get<ReadableEvent>(handle); 1578
1579 if (evt == nullptr) { 1579 auto writable_event = handle_table.Get<WritableEvent>(handle);
1580 LOG_ERROR(Kernel_SVC, "Event handle does not exist, handle=0x{:08X}", handle); 1580 if (writable_event) {
1581 return ERR_INVALID_HANDLE; 1581 writable_event->Clear();
1582 return RESULT_SUCCESS;
1582 } 1583 }
1583 1584
1584 evt->Clear(); 1585 auto readable_event = handle_table.Get<ReadableEvent>(handle);
1585 return RESULT_SUCCESS; 1586 if (readable_event) {
1587 readable_event->Clear();
1588 return RESULT_SUCCESS;
1589 }
1590
1591 LOG_ERROR(Kernel_SVC, "Event handle does not exist, handle=0x{:08X}", handle);
1592 return ERR_INVALID_HANDLE;
1586} 1593}
1587 1594
1588static ResultCode GetProcessInfo(u64* out, Handle process_handle, u32 type) { 1595static ResultCode GetProcessInfo(u64* out, Handle process_handle, u32 type) {
diff --git a/src/core/hle/kernel/writable_event.h b/src/core/hle/kernel/writable_event.h
index fc57d18d7..8fa8d68ee 100644
--- a/src/core/hle/kernel/writable_event.h
+++ b/src/core/hle/kernel/writable_event.h
@@ -39,7 +39,7 @@ public:
39 return name; 39 return name;
40 } 40 }
41 41
42 static const HandleType HANDLE_TYPE = HandleType::Event; 42 static const HandleType HANDLE_TYPE = HandleType::WritableEvent;
43 HandleType GetHandleType() const override { 43 HandleType GetHandleType() const override {
44 return HANDLE_TYPE; 44 return HANDLE_TYPE;
45 } 45 }
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp
index 96c57fe97..f9c18ede4 100644
--- a/src/yuzu/debugger/wait_tree.cpp
+++ b/src/yuzu/debugger/wait_tree.cpp
@@ -153,7 +153,7 @@ QString WaitTreeWaitObject::GetText() const {
153 153
154std::unique_ptr<WaitTreeWaitObject> WaitTreeWaitObject::make(const Kernel::WaitObject& object) { 154std::unique_ptr<WaitTreeWaitObject> WaitTreeWaitObject::make(const Kernel::WaitObject& object) {
155 switch (object.GetHandleType()) { 155 switch (object.GetHandleType()) {
156 case Kernel::HandleType::Event: 156 case Kernel::HandleType::ReadableEvent:
157 return std::make_unique<WaitTreeEvent>(static_cast<const Kernel::ReadableEvent&>(object)); 157 return std::make_unique<WaitTreeEvent>(static_cast<const Kernel::ReadableEvent&>(object));
158 case Kernel::HandleType::Timer: 158 case Kernel::HandleType::Timer:
159 return std::make_unique<WaitTreeTimer>(static_cast<const Kernel::Timer&>(object)); 159 return std::make_unique<WaitTreeTimer>(static_cast<const Kernel::Timer&>(object));