1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
// Copyright 2017 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <string>
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/client_session.h"
#include "core/hle/service/lm/lm.h"
namespace Service {
namespace LM {
class Logger final : public ServiceFramework<Logger> {
public:
Logger() : ServiceFramework("Logger") {
static const FunctionInfo functions[] = {
{0x00000000, &Logger::Log, "Log"},
};
RegisterHandlers(functions);
}
~Logger() = default;
private:
struct MessageHeader {
u64_le pid;
u64_le threadContext;
union {
BitField<0, 16, u32_le> flags;
BitField<16, 8, u32_le> severity;
BitField<24, 8, u32_le> verbosity;
};
u32_le payload_size;
INSERT_PADDING_WORDS(2);
};
static_assert(sizeof(MessageHeader) == 0x20, "MessageHeader is incorrect size");
/**
* LM::Initialize service function
* Inputs:
* 0: 0x00000000
* Outputs:
* 0: ResultCode
*/
void Log(Kernel::HLERequestContext& ctx) {
MessageHeader header{};
Memory::ReadBlock(ctx.BufferDescriptorX()[0].Address(), &header, sizeof(MessageHeader));
std::vector<char> string(header.payload_size);
Memory::ReadBlock(ctx.BufferDescriptorX()[0].Address() + sizeof(MessageHeader),
string.data(), header.payload_size);
LOG_DEBUG(Debug_Emulated, "%.*s", header.payload_size, string.data());
IPC::RequestBuilder rb{ctx, 1};
rb.Push(RESULT_SUCCESS);
}
};
void InstallInterfaces(SM::ServiceManager& service_manager) {
std::make_shared<LM>()->InstallAsService(service_manager);
}
/**
* LM::Initialize service function
* Inputs:
* 0: 0x00000000
* Outputs:
* 0: ResultCode
*/
void LM::Initialize(Kernel::HLERequestContext& ctx) {
auto client_port = std::make_shared<Logger>()->CreatePort();
auto session = client_port->Connect();
if (session.Succeeded()) {
LOG_DEBUG(Service_SM, "called, initialized logger -> session=%u",
(*session)->GetObjectId());
IPC::RequestBuilder rb{ctx, 1, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushObjects(std::move(session).Unwrap());
registered_loggers.emplace_back(std::move(client_port));
} else {
UNIMPLEMENTED();
}
LOG_INFO(Service_SM, "called");
}
LM::LM() : ServiceFramework("lm") {
static const FunctionInfo functions[] = {
{0x00000000, &LM::Initialize, "Initialize"},
};
RegisterHandlers(functions);
}
LM::~LM() = default;
} // namespace LM
} // namespace Service
|