summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar mailwl2018-02-13 09:44:53 +0300
committerGravatar mailwl2018-02-13 09:44:53 +0300
commit55de13efcce5a940d6b9999885b45d70f6719711 (patch)
treeb8f32584323b0c65182d780faafad4e2d2bb1e25 /src
parentMerge pull request #179 from gdkchan/audren_stubs (diff)
downloadyuzu-55de13efcce5a940d6b9999885b45d70f6719711.tar.gz
yuzu-55de13efcce5a940d6b9999885b45d70f6719711.tar.xz
yuzu-55de13efcce5a940d6b9999885b45d70f6719711.zip
Service/lm: add support to multiline logs
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/lm/lm.cpp69
1 files changed, 49 insertions, 20 deletions
diff --git a/src/core/hle/service/lm/lm.cpp b/src/core/hle/service/lm/lm.cpp
index c480f6b97..b8e53d2c7 100644
--- a/src/core/hle/service/lm/lm.cpp
+++ b/src/core/hle/service/lm/lm.cpp
@@ -2,6 +2,7 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <sstream>
5#include <string> 6#include <string>
6#include "common/logging/log.h" 7#include "common/logging/log.h"
7#include "core/hle/ipc_helpers.h" 8#include "core/hle/ipc_helpers.h"
@@ -28,19 +29,28 @@ private:
28 IsHead = 1, 29 IsHead = 1,
29 IsTail = 2, 30 IsTail = 2,
30 }; 31 };
32 enum Severity : u32_le {
33 Trace,
34 Info,
35 Warning,
36 Error,
37 Critical,
38 };
31 39
32 u64_le pid; 40 u64_le pid;
33 u64_le threadContext; 41 u64_le threadContext;
34 union { 42 union {
35 BitField<0, 16, Flags> flags; 43 BitField<0, 16, Flags> flags;
36 BitField<16, 8, u32_le> severity; 44 BitField<16, 8, Severity> severity;
37 BitField<24, 8, u32_le> verbosity; 45 BitField<24, 8, u32_le> verbosity;
38 }; 46 };
39 u32_le payload_size; 47 u32_le payload_size;
40 48
41 /// Returns true if this is part of a single log message 49 bool IsHeadLog() const {
42 bool IsSingleMessage() const { 50 return flags & Flags::IsHead;
43 return (flags & Flags::IsHead) && (flags & Flags::IsTail); 51 }
52 bool IsTailLog() const {
53 return flags & Flags::IsTail;
44 } 54 }
45 }; 55 };
46 static_assert(sizeof(MessageHeader) == 0x18, "MessageHeader is incorrect size"); 56 static_assert(sizeof(MessageHeader) == 0x18, "MessageHeader is incorrect size");
@@ -57,7 +67,7 @@ private:
57 }; 67 };
58 68
59 /** 69 /**
60 * LM::Initialize service function 70 * LM::Log service function
61 * Inputs: 71 * Inputs:
62 * 0: 0x00000000 72 * 0: 0x00000000
63 * Outputs: 73 * Outputs:
@@ -75,9 +85,9 @@ private:
75 Memory::ReadBlock(addr, &header, sizeof(MessageHeader)); 85 Memory::ReadBlock(addr, &header, sizeof(MessageHeader));
76 addr += sizeof(MessageHeader); 86 addr += sizeof(MessageHeader);
77 87
78 if (!header.IsSingleMessage()) { 88 if (header.IsHeadLog()) {
79 LOG_WARNING(Service_LM, "Multi message logs are unimplemeneted"); 89 log_stream.str("");
80 return; 90 log_stream.clear();
81 } 91 }
82 92
83 // Parse out log metadata 93 // Parse out log metadata
@@ -85,7 +95,7 @@ private:
85 std::string message, filename, function; 95 std::string message, filename, function;
86 while (addr < end_addr) { 96 while (addr < end_addr) {
87 const Field field{static_cast<Field>(Memory::Read8(addr++))}; 97 const Field field{static_cast<Field>(Memory::Read8(addr++))};
88 size_t length{Memory::Read8(addr++)}; 98 const size_t length{Memory::Read8(addr++)};
89 99
90 if (static_cast<Field>(Memory::Read8(addr)) == Field::Skip) { 100 if (static_cast<Field>(Memory::Read8(addr)) == Field::Skip) {
91 ++addr; 101 ++addr;
@@ -110,28 +120,47 @@ private:
110 } 120 }
111 121
112 // Empty log - nothing to do here 122 // Empty log - nothing to do here
113 if (message.empty()) { 123 if (log_stream.str().empty() && message.empty()) {
114 return; 124 return;
115 } 125 }
116 126
117 // Format a nicely printable string out of the log metadata 127 // Format a nicely printable string out of the log metadata
118 std::string output; 128 if (!filename.empty()) {
119 if (filename.size()) { 129 log_stream << filename << ':';
120 output += filename + ':';
121 } 130 }
122 if (function.size()) { 131 if (!function.empty()) {
123 output += function + ':'; 132 log_stream << function << ':';
124 } 133 }
125 if (line) { 134 if (line) {
126 output += std::to_string(line) + ':'; 135 log_stream << std::to_string(line) << ':';
127 } 136 }
128 if (output.length() > 0 && output.back() == ':') { 137 if (log_stream.str().length() > 0 && log_stream.str().back() == ':') {
129 output += ' '; 138 log_stream << ' ';
130 } 139 }
131 output += message; 140 log_stream << message;
132 141
133 LOG_INFO(Debug_Emulated, "%s", output.c_str()); 142 if (header.IsTailLog()) {
143 switch (header.severity) {
144 case MessageHeader::Severity::Trace:
145 LOG_TRACE(Debug_Emulated, "%s", log_stream.str().c_str());
146 break;
147 case MessageHeader::Severity::Info:
148 LOG_INFO(Debug_Emulated, "%s", log_stream.str().c_str());
149 break;
150 case MessageHeader::Severity::Warning:
151 LOG_WARNING(Debug_Emulated, "%s", log_stream.str().c_str());
152 break;
153 case MessageHeader::Severity::Error:
154 LOG_ERROR(Debug_Emulated, "%s", log_stream.str().c_str());
155 break;
156 case MessageHeader::Severity::Critical:
157 LOG_CRITICAL(Debug_Emulated, "%s", log_stream.str().c_str());
158 break;
159 }
160 }
134 } 161 }
162
163 std::ostringstream log_stream;
135}; 164};
136 165
137void InstallInterfaces(SM::ServiceManager& service_manager) { 166void InstallInterfaces(SM::ServiceManager& service_manager) {