mirror of
https://github.com/PabloMK7/citra.git
synced 2025-09-12 22:00:04 +00:00
Merge branch 'master' into feature/savestates-2
This commit is contained in:
commit
da3ab3d56e
80 changed files with 7297 additions and 2608 deletions
|
@ -6,9 +6,7 @@
|
|||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#ifndef _MSC_VER
|
||||
#include <cstddef>
|
||||
#endif
|
||||
#include <memory>
|
||||
#include "common/bit_field.h"
|
||||
#include "common/common_funcs.h"
|
||||
|
@ -177,10 +175,6 @@ struct GyroscopeCalibrateParam {
|
|||
} x, y, z;
|
||||
};
|
||||
|
||||
// TODO: MSVC does not support using offsetof() on non-static data members even though this
|
||||
// is technically allowed since C++11. This macro should be enabled once MSVC adds
|
||||
// support for that.
|
||||
#ifndef _MSC_VER
|
||||
#define ASSERT_REG_POSITION(field_name, position) \
|
||||
static_assert(offsetof(SharedMem, field_name) == position * 4, \
|
||||
"Field " #field_name " has invalid position")
|
||||
|
@ -189,7 +183,6 @@ ASSERT_REG_POSITION(pad.index_reset_ticks, 0x0);
|
|||
ASSERT_REG_POSITION(touch.index_reset_ticks, 0x2A);
|
||||
|
||||
#undef ASSERT_REG_POSITION
|
||||
#endif // !defined(_MSC_VER)
|
||||
|
||||
struct DirectionState {
|
||||
bool up;
|
||||
|
|
|
@ -2,9 +2,14 @@
|
|||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <atomic>
|
||||
#ifdef ENABLE_WEB_SERVICE
|
||||
#include <LUrlParser.h>
|
||||
#endif
|
||||
#include <cryptopp/aes.h>
|
||||
#include <cryptopp/modes.h>
|
||||
#include "common/archives.h"
|
||||
#include "common/assert.h"
|
||||
#include "core/core.h"
|
||||
#include "core/file_sys/archive_ncch.h"
|
||||
#include "core/file_sys/file_backend.h"
|
||||
|
@ -52,6 +57,82 @@ const ResultCode ERROR_WRONG_CERT_HANDLE = // 0xD8A0A0C9
|
|||
const ResultCode ERROR_CERT_ALREADY_SET = // 0xD8A0A03D
|
||||
ResultCode(61, ErrorModule::HTTP, ErrorSummary::InvalidState, ErrorLevel::Permanent);
|
||||
|
||||
void Context::MakeRequest() {
|
||||
ASSERT(state == RequestState::NotStarted);
|
||||
|
||||
#ifdef ENABLE_WEB_SERVICE
|
||||
LUrlParser::clParseURL parsedUrl = LUrlParser::clParseURL::ParseURL(url);
|
||||
int port;
|
||||
std::unique_ptr<httplib::Client> client;
|
||||
if (parsedUrl.m_Scheme == "http") {
|
||||
if (!parsedUrl.GetPort(&port)) {
|
||||
port = 80;
|
||||
}
|
||||
// TODO(B3N30): Support for setting timeout
|
||||
// Figure out what the default timeout on 3DS is
|
||||
client = std::make_unique<httplib::Client>(parsedUrl.m_Host.c_str(), port);
|
||||
} else {
|
||||
if (!parsedUrl.GetPort(&port)) {
|
||||
port = 443;
|
||||
}
|
||||
// TODO(B3N30): Support for setting timeout
|
||||
// Figure out what the default timeout on 3DS is
|
||||
|
||||
auto ssl_client = std::make_unique<httplib::SSLClient>(parsedUrl.m_Host, port);
|
||||
SSL_CTX* ctx = ssl_client->ssl_context();
|
||||
client = std::move(ssl_client);
|
||||
|
||||
if (auto client_cert = ssl_config.client_cert_ctx.lock()) {
|
||||
SSL_CTX_use_certificate_ASN1(ctx, client_cert->certificate.size(),
|
||||
client_cert->certificate.data());
|
||||
SSL_CTX_use_PrivateKey_ASN1(EVP_PKEY_RSA, ctx, client_cert->private_key.data(),
|
||||
client_cert->private_key.size());
|
||||
}
|
||||
|
||||
// TODO(B3N30): Check for SSLOptions-Bits and set the verify method accordingly
|
||||
// https://www.3dbrew.org/wiki/SSL_Services#SSLOpt
|
||||
// Hack: Since for now RootCerts are not implemented we set the VerifyMode to None.
|
||||
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
|
||||
}
|
||||
|
||||
state = RequestState::InProgress;
|
||||
|
||||
static const std::unordered_map<RequestMethod, std::string> request_method_strings{
|
||||
{RequestMethod::Get, "GET"}, {RequestMethod::Post, "POST"},
|
||||
{RequestMethod::Head, "HEAD"}, {RequestMethod::Put, "PUT"},
|
||||
{RequestMethod::Delete, "DELETE"}, {RequestMethod::PostEmpty, "POST"},
|
||||
{RequestMethod::PutEmpty, "PUT"},
|
||||
};
|
||||
|
||||
httplib::Request request;
|
||||
request.method = request_method_strings.at(method);
|
||||
request.path = url;
|
||||
// TODO(B3N30): Add post data body
|
||||
request.progress = [this](u64 current, u64 total) -> bool {
|
||||
// TODO(B3N30): Is there a state that shows response header are available
|
||||
current_download_size_bytes = current;
|
||||
total_download_size_bytes = total;
|
||||
return true;
|
||||
};
|
||||
|
||||
for (const auto& header : headers) {
|
||||
request.headers.emplace(header.name, header.value);
|
||||
}
|
||||
|
||||
if (!client->send(request, response)) {
|
||||
LOG_ERROR(Service_HTTP, "Request failed");
|
||||
state = RequestState::TimedOut;
|
||||
} else {
|
||||
LOG_DEBUG(Service_HTTP, "Request successful");
|
||||
// TODO(B3N30): Verify this state on HW
|
||||
state = RequestState::ReadyToDownloadContent;
|
||||
}
|
||||
#else
|
||||
LOG_ERROR(Service_HTTP, "Tried to make request but WebServices is not enabled in this build");
|
||||
state = RequestState::TimedOut;
|
||||
#endif
|
||||
}
|
||||
|
||||
void HTTP_C::Initialize(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x1, 1, 4);
|
||||
const u32 shmem_size = rp.Pop<u32>();
|
||||
|
@ -156,7 +237,15 @@ void HTTP_C::BeginRequest(Kernel::HLERequestContext& ctx) {
|
|||
auto itr = contexts.find(context_handle);
|
||||
ASSERT(itr != contexts.end());
|
||||
|
||||
// TODO(B3N30): Make the request
|
||||
// On a 3DS BeginRequest and BeginRequestAsync will push the Request to a worker queue.
|
||||
// You can only enqueue 8 requests at the same time.
|
||||
// trying to enqueue any more will either fail (BeginRequestAsync), or block (BeginRequest)
|
||||
// Note that you only can have 8 Contexts at a time. So this difference shouldn't matter
|
||||
// Then there are 3? worker threads that pop the requests from the queue and send them
|
||||
// For now make every request async in it's own thread.
|
||||
|
||||
itr->second.request_future =
|
||||
std::async(std::launch::async, &Context::MakeRequest, std::ref(itr->second));
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
@ -201,7 +290,15 @@ void HTTP_C::BeginRequestAsync(Kernel::HLERequestContext& ctx) {
|
|||
auto itr = contexts.find(context_handle);
|
||||
ASSERT(itr != contexts.end());
|
||||
|
||||
// TODO(B3N30): Make the request
|
||||
// On a 3DS BeginRequest and BeginRequestAsync will push the Request to a worker queue.
|
||||
// You can only enqueue 8 requests at the same time.
|
||||
// trying to enqueue any more will either fail (BeginRequestAsync), or block (BeginRequest)
|
||||
// Note that you only can have 8 Contexts at a time. So this difference shouldn't matter
|
||||
// Then there are 3? worker threads that pop the requests from the queue and send them
|
||||
// For now make every request async in it's own thread.
|
||||
|
||||
itr->second.request_future =
|
||||
std::async(std::launch::async, &Context::MakeRequest, std::ref(itr->second));
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
@ -264,7 +361,7 @@ void HTTP_C::CreateContext(Kernel::HLERequestContext& ctx) {
|
|||
return;
|
||||
}
|
||||
|
||||
contexts.emplace(++context_counter, Context());
|
||||
contexts.try_emplace(++context_counter);
|
||||
contexts[context_counter].url = std::move(url);
|
||||
contexts[context_counter].method = method;
|
||||
contexts[context_counter].state = RequestState::NotStarted;
|
||||
|
@ -311,10 +408,9 @@ void HTTP_C::CloseContext(Kernel::HLERequestContext& ctx) {
|
|||
}
|
||||
|
||||
// TODO(Subv): What happens if you try to close a context that's currently being used?
|
||||
ASSERT(itr->second.state == RequestState::NotStarted);
|
||||
|
||||
// TODO(Subv): Make sure that only the session that created the context can close it.
|
||||
|
||||
// Note that this will block if a request is still in progress
|
||||
contexts.erase(itr);
|
||||
session_data->num_http_contexts--;
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <future>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
@ -15,6 +16,12 @@
|
|||
#include <boost/serialization/unordered_map.hpp>
|
||||
#include <boost/serialization/vector.hpp>
|
||||
#include <boost/serialization/weak_ptr.hpp>
|
||||
#ifdef ENABLE_WEB_SERVICE
|
||||
#if defined(__ANDROID__)
|
||||
#include <ifaddrs.h>
|
||||
#endif
|
||||
#include <httplib.h>
|
||||
#endif
|
||||
#include "core/hle/kernel/shared_memory.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
|
@ -113,8 +120,7 @@ public:
|
|||
Context(const Context&) = delete;
|
||||
Context& operator=(const Context&) = delete;
|
||||
|
||||
Context(Context&& other) = default;
|
||||
Context& operator=(Context&&) = default;
|
||||
void MakeRequest();
|
||||
|
||||
struct Proxy {
|
||||
std::string url;
|
||||
|
@ -195,14 +201,21 @@ public:
|
|||
u32 session_id;
|
||||
std::string url;
|
||||
RequestMethod method;
|
||||
RequestState state = RequestState::NotStarted;
|
||||
boost::optional<Proxy> proxy;
|
||||
boost::optional<BasicAuth> basic_auth;
|
||||
std::atomic<RequestState> state = RequestState::NotStarted;
|
||||
std::optional<Proxy> proxy;
|
||||
std::optional<BasicAuth> basic_auth;
|
||||
SSLConfig ssl_config{};
|
||||
u32 socket_buffer_size;
|
||||
std::vector<RequestHeader> headers;
|
||||
std::vector<PostData> post_data;
|
||||
|
||||
std::future<void> request_future;
|
||||
std::atomic<u64> current_download_size_bytes;
|
||||
std::atomic<u64> total_download_size_bytes;
|
||||
#ifdef ENABLE_WEB_SERVICE
|
||||
httplib::Response response;
|
||||
#endif
|
||||
|
||||
private:
|
||||
template <class Archive>
|
||||
void serialize(Archive& ar, const unsigned int) {
|
||||
|
@ -219,6 +232,7 @@ private:
|
|||
ar& post_data;
|
||||
}
|
||||
friend class boost::serialization::access;
|
||||
|
||||
};
|
||||
|
||||
struct SessionData : public Kernel::SessionRequestHandler::SessionDataBase {
|
||||
|
|
|
@ -55,7 +55,7 @@ VAddr CROHelper::SegmentTagToAddress(SegmentTag segment_tag) const {
|
|||
return 0;
|
||||
|
||||
SegmentEntry entry;
|
||||
GetEntry(memory, segment_tag.segment_index, entry);
|
||||
GetEntry(system.Memory(), segment_tag.segment_index, entry);
|
||||
|
||||
if (segment_tag.offset_into_segment >= entry.size)
|
||||
return 0;
|
||||
|
@ -71,12 +71,12 @@ ResultCode CROHelper::ApplyRelocation(VAddr target_address, RelocationType reloc
|
|||
break;
|
||||
case RelocationType::AbsoluteAddress:
|
||||
case RelocationType::AbsoluteAddress2:
|
||||
memory.Write32(target_address, symbol_address + addend);
|
||||
cpu.InvalidateCacheRange(target_address, sizeof(u32));
|
||||
system.Memory().Write32(target_address, symbol_address + addend);
|
||||
system.InvalidateCacheRange(target_address, sizeof(u32));
|
||||
break;
|
||||
case RelocationType::RelativeAddress:
|
||||
memory.Write32(target_address, symbol_address + addend - target_future_address);
|
||||
cpu.InvalidateCacheRange(target_address, sizeof(u32));
|
||||
system.Memory().Write32(target_address, symbol_address + addend - target_future_address);
|
||||
system.InvalidateCacheRange(target_address, sizeof(u32));
|
||||
break;
|
||||
case RelocationType::ThumbBranch:
|
||||
case RelocationType::ArmBranch:
|
||||
|
@ -98,8 +98,8 @@ ResultCode CROHelper::ClearRelocation(VAddr target_address, RelocationType reloc
|
|||
case RelocationType::AbsoluteAddress:
|
||||
case RelocationType::AbsoluteAddress2:
|
||||
case RelocationType::RelativeAddress:
|
||||
memory.Write32(target_address, 0);
|
||||
cpu.InvalidateCacheRange(target_address, sizeof(u32));
|
||||
system.Memory().Write32(target_address, 0);
|
||||
system.InvalidateCacheRange(target_address, sizeof(u32));
|
||||
break;
|
||||
case RelocationType::ThumbBranch:
|
||||
case RelocationType::ArmBranch:
|
||||
|
@ -121,7 +121,8 @@ ResultCode CROHelper::ApplyRelocationBatch(VAddr batch, u32 symbol_address, bool
|
|||
VAddr relocation_address = batch;
|
||||
while (true) {
|
||||
RelocationEntry relocation;
|
||||
memory.ReadBlock(process, relocation_address, &relocation, sizeof(RelocationEntry));
|
||||
system.Memory().ReadBlock(process, relocation_address, &relocation,
|
||||
sizeof(RelocationEntry));
|
||||
|
||||
VAddr relocation_target = SegmentTagToAddress(relocation.target_position);
|
||||
if (relocation_target == 0) {
|
||||
|
@ -142,9 +143,9 @@ ResultCode CROHelper::ApplyRelocationBatch(VAddr batch, u32 symbol_address, bool
|
|||
}
|
||||
|
||||
RelocationEntry relocation;
|
||||
memory.ReadBlock(process, batch, &relocation, sizeof(RelocationEntry));
|
||||
system.Memory().ReadBlock(process, batch, &relocation, sizeof(RelocationEntry));
|
||||
relocation.is_batch_resolved = reset ? 0 : 1;
|
||||
memory.WriteBlock(process, batch, &relocation, sizeof(RelocationEntry));
|
||||
system.Memory().WriteBlock(process, batch, &relocation, sizeof(RelocationEntry));
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -154,13 +155,13 @@ VAddr CROHelper::FindExportNamedSymbol(const std::string& name) const {
|
|||
|
||||
std::size_t len = name.size();
|
||||
ExportTreeEntry entry;
|
||||
GetEntry(memory, 0, entry);
|
||||
GetEntry(system.Memory(), 0, entry);
|
||||
ExportTreeEntry::Child next;
|
||||
next.raw = entry.left.raw;
|
||||
u32 found_id;
|
||||
|
||||
while (true) {
|
||||
GetEntry(memory, next.next_index, entry);
|
||||
GetEntry(system.Memory(), next.next_index, entry);
|
||||
|
||||
if (next.is_end) {
|
||||
found_id = entry.export_table_index;
|
||||
|
@ -186,9 +187,9 @@ VAddr CROHelper::FindExportNamedSymbol(const std::string& name) const {
|
|||
|
||||
u32 export_strings_size = GetField(ExportStringsSize);
|
||||
ExportNamedSymbolEntry symbol_entry;
|
||||
GetEntry(memory, found_id, symbol_entry);
|
||||
GetEntry(system.Memory(), found_id, symbol_entry);
|
||||
|
||||
if (memory.ReadCString(symbol_entry.name_offset, export_strings_size) != name)
|
||||
if (system.Memory().ReadCString(symbol_entry.name_offset, export_strings_size) != name)
|
||||
return 0;
|
||||
|
||||
return SegmentTagToAddress(symbol_entry.symbol_position);
|
||||
|
@ -279,7 +280,7 @@ ResultVal<VAddr> CROHelper::RebaseSegmentTable(u32 cro_size, VAddr data_segment_
|
|||
u32 segment_num = GetField(SegmentNum);
|
||||
for (u32 i = 0; i < segment_num; ++i) {
|
||||
SegmentEntry segment;
|
||||
GetEntry(memory, i, segment);
|
||||
GetEntry(system.Memory(), i, segment);
|
||||
if (segment.type == SegmentType::Data) {
|
||||
if (segment.size != 0) {
|
||||
if (segment.size > data_segment_size)
|
||||
|
@ -298,7 +299,7 @@ ResultVal<VAddr> CROHelper::RebaseSegmentTable(u32 cro_size, VAddr data_segment_
|
|||
if (segment.offset > module_address + cro_size)
|
||||
return CROFormatError(0x19);
|
||||
}
|
||||
SetEntry(memory, i, segment);
|
||||
SetEntry(system.Memory(), i, segment);
|
||||
}
|
||||
return MakeResult<u32>(prev_data_segment + module_address);
|
||||
}
|
||||
|
@ -310,7 +311,7 @@ ResultCode CROHelper::RebaseExportNamedSymbolTable() {
|
|||
u32 export_named_symbol_num = GetField(ExportNamedSymbolNum);
|
||||
for (u32 i = 0; i < export_named_symbol_num; ++i) {
|
||||
ExportNamedSymbolEntry entry;
|
||||
GetEntry(memory, i, entry);
|
||||
GetEntry(system.Memory(), i, entry);
|
||||
|
||||
if (entry.name_offset != 0) {
|
||||
entry.name_offset += module_address;
|
||||
|
@ -320,7 +321,7 @@ ResultCode CROHelper::RebaseExportNamedSymbolTable() {
|
|||
}
|
||||
}
|
||||
|
||||
SetEntry(memory, i, entry);
|
||||
SetEntry(system.Memory(), i, entry);
|
||||
}
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
@ -329,7 +330,7 @@ ResultCode CROHelper::VerifyExportTreeTable() const {
|
|||
u32 tree_num = GetField(ExportTreeNum);
|
||||
for (u32 i = 0; i < tree_num; ++i) {
|
||||
ExportTreeEntry entry;
|
||||
GetEntry(memory, i, entry);
|
||||
GetEntry(system.Memory(), i, entry);
|
||||
|
||||
if (entry.left.next_index >= tree_num || entry.right.next_index >= tree_num) {
|
||||
return CROFormatError(0x11);
|
||||
|
@ -353,7 +354,7 @@ ResultCode CROHelper::RebaseImportModuleTable() {
|
|||
u32 module_num = GetField(ImportModuleNum);
|
||||
for (u32 i = 0; i < module_num; ++i) {
|
||||
ImportModuleEntry entry;
|
||||
GetEntry(memory, i, entry);
|
||||
GetEntry(system.Memory(), i, entry);
|
||||
|
||||
if (entry.name_offset != 0) {
|
||||
entry.name_offset += module_address;
|
||||
|
@ -379,7 +380,7 @@ ResultCode CROHelper::RebaseImportModuleTable() {
|
|||
}
|
||||
}
|
||||
|
||||
SetEntry(memory, i, entry);
|
||||
SetEntry(system.Memory(), i, entry);
|
||||
}
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
@ -395,7 +396,7 @@ ResultCode CROHelper::RebaseImportNamedSymbolTable() {
|
|||
u32 num = GetField(ImportNamedSymbolNum);
|
||||
for (u32 i = 0; i < num; ++i) {
|
||||
ImportNamedSymbolEntry entry;
|
||||
GetEntry(memory, i, entry);
|
||||
GetEntry(system.Memory(), i, entry);
|
||||
|
||||
if (entry.name_offset != 0) {
|
||||
entry.name_offset += module_address;
|
||||
|
@ -413,7 +414,7 @@ ResultCode CROHelper::RebaseImportNamedSymbolTable() {
|
|||
}
|
||||
}
|
||||
|
||||
SetEntry(memory, i, entry);
|
||||
SetEntry(system.Memory(), i, entry);
|
||||
}
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
@ -427,7 +428,7 @@ ResultCode CROHelper::RebaseImportIndexedSymbolTable() {
|
|||
u32 num = GetField(ImportIndexedSymbolNum);
|
||||
for (u32 i = 0; i < num; ++i) {
|
||||
ImportIndexedSymbolEntry entry;
|
||||
GetEntry(memory, i, entry);
|
||||
GetEntry(system.Memory(), i, entry);
|
||||
|
||||
if (entry.relocation_batch_offset != 0) {
|
||||
entry.relocation_batch_offset += module_address;
|
||||
|
@ -437,7 +438,7 @@ ResultCode CROHelper::RebaseImportIndexedSymbolTable() {
|
|||
}
|
||||
}
|
||||
|
||||
SetEntry(memory, i, entry);
|
||||
SetEntry(system.Memory(), i, entry);
|
||||
}
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
@ -451,7 +452,7 @@ ResultCode CROHelper::RebaseImportAnonymousSymbolTable() {
|
|||
u32 num = GetField(ImportAnonymousSymbolNum);
|
||||
for (u32 i = 0; i < num; ++i) {
|
||||
ImportAnonymousSymbolEntry entry;
|
||||
GetEntry(memory, i, entry);
|
||||
GetEntry(system.Memory(), i, entry);
|
||||
|
||||
if (entry.relocation_batch_offset != 0) {
|
||||
entry.relocation_batch_offset += module_address;
|
||||
|
@ -461,7 +462,7 @@ ResultCode CROHelper::RebaseImportAnonymousSymbolTable() {
|
|||
}
|
||||
}
|
||||
|
||||
SetEntry(memory, i, entry);
|
||||
SetEntry(system.Memory(), i, entry);
|
||||
}
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
@ -476,14 +477,14 @@ ResultCode CROHelper::ResetExternalRelocations() {
|
|||
ExternalRelocationEntry relocation;
|
||||
|
||||
// Verifies that the last relocation is the end of a batch
|
||||
GetEntry(memory, external_relocation_num - 1, relocation);
|
||||
GetEntry(system.Memory(), external_relocation_num - 1, relocation);
|
||||
if (!relocation.is_batch_end) {
|
||||
return CROFormatError(0x12);
|
||||
}
|
||||
|
||||
bool batch_begin = true;
|
||||
for (u32 i = 0; i < external_relocation_num; ++i) {
|
||||
GetEntry(memory, i, relocation);
|
||||
GetEntry(system.Memory(), i, relocation);
|
||||
VAddr relocation_target = SegmentTagToAddress(relocation.target_position);
|
||||
|
||||
if (relocation_target == 0) {
|
||||
|
@ -500,7 +501,7 @@ ResultCode CROHelper::ResetExternalRelocations() {
|
|||
if (batch_begin) {
|
||||
// resets to unresolved state
|
||||
relocation.is_batch_resolved = 0;
|
||||
SetEntry(memory, i, relocation);
|
||||
SetEntry(system.Memory(), i, relocation);
|
||||
}
|
||||
|
||||
// if current is an end, then the next is a beginning
|
||||
|
@ -516,7 +517,7 @@ ResultCode CROHelper::ClearExternalRelocations() {
|
|||
|
||||
bool batch_begin = true;
|
||||
for (u32 i = 0; i < external_relocation_num; ++i) {
|
||||
GetEntry(memory, i, relocation);
|
||||
GetEntry(system.Memory(), i, relocation);
|
||||
VAddr relocation_target = SegmentTagToAddress(relocation.target_position);
|
||||
|
||||
if (relocation_target == 0) {
|
||||
|
@ -532,7 +533,7 @@ ResultCode CROHelper::ClearExternalRelocations() {
|
|||
if (batch_begin) {
|
||||
// resets to unresolved state
|
||||
relocation.is_batch_resolved = 0;
|
||||
SetEntry(memory, i, relocation);
|
||||
SetEntry(system.Memory(), i, relocation);
|
||||
}
|
||||
|
||||
// if current is an end, then the next is a beginning
|
||||
|
@ -548,13 +549,13 @@ ResultCode CROHelper::ApplyStaticAnonymousSymbolToCRS(VAddr crs_address) {
|
|||
static_relocation_table_offset +
|
||||
GetField(StaticRelocationNum) * sizeof(StaticRelocationEntry);
|
||||
|
||||
CROHelper crs(crs_address, process, memory, cpu);
|
||||
CROHelper crs(crs_address, process, system);
|
||||
u32 offset_export_num = GetField(StaticAnonymousSymbolNum);
|
||||
LOG_INFO(Service_LDR, "CRO \"{}\" exports {} static anonymous symbols", ModuleName(),
|
||||
offset_export_num);
|
||||
for (u32 i = 0; i < offset_export_num; ++i) {
|
||||
StaticAnonymousSymbolEntry entry;
|
||||
GetEntry(memory, i, entry);
|
||||
GetEntry(system.Memory(), i, entry);
|
||||
u32 batch_address = entry.relocation_batch_offset + module_address;
|
||||
|
||||
if (batch_address < static_relocation_table_offset ||
|
||||
|
@ -579,7 +580,7 @@ ResultCode CROHelper::ApplyInternalRelocations(u32 old_data_segment_address) {
|
|||
u32 internal_relocation_num = GetField(InternalRelocationNum);
|
||||
for (u32 i = 0; i < internal_relocation_num; ++i) {
|
||||
InternalRelocationEntry relocation;
|
||||
GetEntry(memory, i, relocation);
|
||||
GetEntry(system.Memory(), i, relocation);
|
||||
VAddr target_addressB = SegmentTagToAddress(relocation.target_position);
|
||||
if (target_addressB == 0) {
|
||||
return CROFormatError(0x15);
|
||||
|
@ -587,7 +588,7 @@ ResultCode CROHelper::ApplyInternalRelocations(u32 old_data_segment_address) {
|
|||
|
||||
VAddr target_address;
|
||||
SegmentEntry target_segment;
|
||||
GetEntry(memory, relocation.target_position.segment_index, target_segment);
|
||||
GetEntry(system.Memory(), relocation.target_position.segment_index, target_segment);
|
||||
|
||||
if (target_segment.type == SegmentType::Data) {
|
||||
// If the relocation is to the .data segment, we need to relocate it in the old buffer
|
||||
|
@ -602,7 +603,7 @@ ResultCode CROHelper::ApplyInternalRelocations(u32 old_data_segment_address) {
|
|||
}
|
||||
|
||||
SegmentEntry symbol_segment;
|
||||
GetEntry(memory, relocation.symbol_segment, symbol_segment);
|
||||
GetEntry(system.Memory(), relocation.symbol_segment, symbol_segment);
|
||||
LOG_TRACE(Service_LDR, "Internally relocates 0x{:08X} with 0x{:08X}", target_address,
|
||||
symbol_segment.offset);
|
||||
ResultCode result = ApplyRelocation(target_address, relocation.type, relocation.addend,
|
||||
|
@ -619,7 +620,7 @@ ResultCode CROHelper::ClearInternalRelocations() {
|
|||
u32 internal_relocation_num = GetField(InternalRelocationNum);
|
||||
for (u32 i = 0; i < internal_relocation_num; ++i) {
|
||||
InternalRelocationEntry relocation;
|
||||
GetEntry(memory, i, relocation);
|
||||
GetEntry(system.Memory(), i, relocation);
|
||||
VAddr target_address = SegmentTagToAddress(relocation.target_position);
|
||||
|
||||
if (target_address == 0) {
|
||||
|
@ -639,13 +640,13 @@ void CROHelper::UnrebaseImportAnonymousSymbolTable() {
|
|||
u32 num = GetField(ImportAnonymousSymbolNum);
|
||||
for (u32 i = 0; i < num; ++i) {
|
||||
ImportAnonymousSymbolEntry entry;
|
||||
GetEntry(memory, i, entry);
|
||||
GetEntry(system.Memory(), i, entry);
|
||||
|
||||
if (entry.relocation_batch_offset != 0) {
|
||||
entry.relocation_batch_offset -= module_address;
|
||||
}
|
||||
|
||||
SetEntry(memory, i, entry);
|
||||
SetEntry(system.Memory(), i, entry);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -653,13 +654,13 @@ void CROHelper::UnrebaseImportIndexedSymbolTable() {
|
|||
u32 num = GetField(ImportIndexedSymbolNum);
|
||||
for (u32 i = 0; i < num; ++i) {
|
||||
ImportIndexedSymbolEntry entry;
|
||||
GetEntry(memory, i, entry);
|
||||
GetEntry(system.Memory(), i, entry);
|
||||
|
||||
if (entry.relocation_batch_offset != 0) {
|
||||
entry.relocation_batch_offset -= module_address;
|
||||
}
|
||||
|
||||
SetEntry(memory, i, entry);
|
||||
SetEntry(system.Memory(), i, entry);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -667,7 +668,7 @@ void CROHelper::UnrebaseImportNamedSymbolTable() {
|
|||
u32 num = GetField(ImportNamedSymbolNum);
|
||||
for (u32 i = 0; i < num; ++i) {
|
||||
ImportNamedSymbolEntry entry;
|
||||
GetEntry(memory, i, entry);
|
||||
GetEntry(system.Memory(), i, entry);
|
||||
|
||||
if (entry.name_offset != 0) {
|
||||
entry.name_offset -= module_address;
|
||||
|
@ -677,7 +678,7 @@ void CROHelper::UnrebaseImportNamedSymbolTable() {
|
|||
entry.relocation_batch_offset -= module_address;
|
||||
}
|
||||
|
||||
SetEntry(memory, i, entry);
|
||||
SetEntry(system.Memory(), i, entry);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -685,7 +686,7 @@ void CROHelper::UnrebaseImportModuleTable() {
|
|||
u32 module_num = GetField(ImportModuleNum);
|
||||
for (u32 i = 0; i < module_num; ++i) {
|
||||
ImportModuleEntry entry;
|
||||
GetEntry(memory, i, entry);
|
||||
GetEntry(system.Memory(), i, entry);
|
||||
|
||||
if (entry.name_offset != 0) {
|
||||
entry.name_offset -= module_address;
|
||||
|
@ -699,7 +700,7 @@ void CROHelper::UnrebaseImportModuleTable() {
|
|||
entry.import_anonymous_symbol_table_offset -= module_address;
|
||||
}
|
||||
|
||||
SetEntry(memory, i, entry);
|
||||
SetEntry(system.Memory(), i, entry);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -707,13 +708,13 @@ void CROHelper::UnrebaseExportNamedSymbolTable() {
|
|||
u32 export_named_symbol_num = GetField(ExportNamedSymbolNum);
|
||||
for (u32 i = 0; i < export_named_symbol_num; ++i) {
|
||||
ExportNamedSymbolEntry entry;
|
||||
GetEntry(memory, i, entry);
|
||||
GetEntry(system.Memory(), i, entry);
|
||||
|
||||
if (entry.name_offset != 0) {
|
||||
entry.name_offset -= module_address;
|
||||
}
|
||||
|
||||
SetEntry(memory, i, entry);
|
||||
SetEntry(system.Memory(), i, entry);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -721,7 +722,7 @@ void CROHelper::UnrebaseSegmentTable() {
|
|||
u32 segment_num = GetField(SegmentNum);
|
||||
for (u32 i = 0; i < segment_num; ++i) {
|
||||
SegmentEntry segment;
|
||||
GetEntry(memory, i, segment);
|
||||
GetEntry(system.Memory(), i, segment);
|
||||
|
||||
if (segment.type == SegmentType::BSS) {
|
||||
segment.offset = 0;
|
||||
|
@ -729,7 +730,7 @@ void CROHelper::UnrebaseSegmentTable() {
|
|||
segment.offset -= module_address;
|
||||
}
|
||||
|
||||
SetEntry(memory, i, segment);
|
||||
SetEntry(system.Memory(), i, segment);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -751,17 +752,17 @@ ResultCode CROHelper::ApplyImportNamedSymbol(VAddr crs_address) {
|
|||
u32 symbol_import_num = GetField(ImportNamedSymbolNum);
|
||||
for (u32 i = 0; i < symbol_import_num; ++i) {
|
||||
ImportNamedSymbolEntry entry;
|
||||
GetEntry(memory, i, entry);
|
||||
GetEntry(system.Memory(), i, entry);
|
||||
VAddr relocation_addr = entry.relocation_batch_offset;
|
||||
ExternalRelocationEntry relocation_entry;
|
||||
memory.ReadBlock(process, relocation_addr, &relocation_entry,
|
||||
sizeof(ExternalRelocationEntry));
|
||||
system.Memory().ReadBlock(process, relocation_addr, &relocation_entry,
|
||||
sizeof(ExternalRelocationEntry));
|
||||
|
||||
if (!relocation_entry.is_batch_resolved) {
|
||||
ResultCode result = ForEachAutoLinkCRO(
|
||||
process, memory, cpu, crs_address, [&](CROHelper source) -> ResultVal<bool> {
|
||||
process, system, crs_address, [&](CROHelper source) -> ResultVal<bool> {
|
||||
std::string symbol_name =
|
||||
memory.ReadCString(entry.name_offset, import_strings_size);
|
||||
system.Memory().ReadCString(entry.name_offset, import_strings_size);
|
||||
u32 symbol_address = source.FindExportNamedSymbol(symbol_name);
|
||||
|
||||
if (symbol_address != 0) {
|
||||
|
@ -794,11 +795,11 @@ ResultCode CROHelper::ResetImportNamedSymbol() {
|
|||
u32 symbol_import_num = GetField(ImportNamedSymbolNum);
|
||||
for (u32 i = 0; i < symbol_import_num; ++i) {
|
||||
ImportNamedSymbolEntry entry;
|
||||
GetEntry(memory, i, entry);
|
||||
GetEntry(system.Memory(), i, entry);
|
||||
VAddr relocation_addr = entry.relocation_batch_offset;
|
||||
ExternalRelocationEntry relocation_entry;
|
||||
memory.ReadBlock(process, relocation_addr, &relocation_entry,
|
||||
sizeof(ExternalRelocationEntry));
|
||||
system.Memory().ReadBlock(process, relocation_addr, &relocation_entry,
|
||||
sizeof(ExternalRelocationEntry));
|
||||
|
||||
ResultCode result = ApplyRelocationBatch(relocation_addr, unresolved_symbol, true);
|
||||
if (result.IsError()) {
|
||||
|
@ -815,11 +816,11 @@ ResultCode CROHelper::ResetImportIndexedSymbol() {
|
|||
u32 import_num = GetField(ImportIndexedSymbolNum);
|
||||
for (u32 i = 0; i < import_num; ++i) {
|
||||
ImportIndexedSymbolEntry entry;
|
||||
GetEntry(memory, i, entry);
|
||||
GetEntry(system.Memory(), i, entry);
|
||||
VAddr relocation_addr = entry.relocation_batch_offset;
|
||||
ExternalRelocationEntry relocation_entry;
|
||||
memory.ReadBlock(process, relocation_addr, &relocation_entry,
|
||||
sizeof(ExternalRelocationEntry));
|
||||
system.Memory().ReadBlock(process, relocation_addr, &relocation_entry,
|
||||
sizeof(ExternalRelocationEntry));
|
||||
|
||||
ResultCode result = ApplyRelocationBatch(relocation_addr, unresolved_symbol, true);
|
||||
if (result.IsError()) {
|
||||
|
@ -836,11 +837,11 @@ ResultCode CROHelper::ResetImportAnonymousSymbol() {
|
|||
u32 import_num = GetField(ImportAnonymousSymbolNum);
|
||||
for (u32 i = 0; i < import_num; ++i) {
|
||||
ImportAnonymousSymbolEntry entry;
|
||||
GetEntry(memory, i, entry);
|
||||
GetEntry(system.Memory(), i, entry);
|
||||
VAddr relocation_addr = entry.relocation_batch_offset;
|
||||
ExternalRelocationEntry relocation_entry;
|
||||
memory.ReadBlock(process, relocation_addr, &relocation_entry,
|
||||
sizeof(ExternalRelocationEntry));
|
||||
system.Memory().ReadBlock(process, relocation_addr, &relocation_entry,
|
||||
sizeof(ExternalRelocationEntry));
|
||||
|
||||
ResultCode result = ApplyRelocationBatch(relocation_addr, unresolved_symbol, true);
|
||||
if (result.IsError()) {
|
||||
|
@ -857,19 +858,20 @@ ResultCode CROHelper::ApplyModuleImport(VAddr crs_address) {
|
|||
u32 import_module_num = GetField(ImportModuleNum);
|
||||
for (u32 i = 0; i < import_module_num; ++i) {
|
||||
ImportModuleEntry entry;
|
||||
GetEntry(memory, i, entry);
|
||||
std::string want_cro_name = memory.ReadCString(entry.name_offset, import_strings_size);
|
||||
GetEntry(system.Memory(), i, entry);
|
||||
std::string want_cro_name =
|
||||
system.Memory().ReadCString(entry.name_offset, import_strings_size);
|
||||
|
||||
ResultCode result = ForEachAutoLinkCRO(
|
||||
process, memory, cpu, crs_address, [&](CROHelper source) -> ResultVal<bool> {
|
||||
process, system, crs_address, [&](CROHelper source) -> ResultVal<bool> {
|
||||
if (want_cro_name == source.ModuleName()) {
|
||||
LOG_INFO(Service_LDR, "CRO \"{}\" imports {} indexed symbols from \"{}\"",
|
||||
ModuleName(), entry.import_indexed_symbol_num, source.ModuleName());
|
||||
for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) {
|
||||
ImportIndexedSymbolEntry im;
|
||||
entry.GetImportIndexedSymbolEntry(process, memory, j, im);
|
||||
entry.GetImportIndexedSymbolEntry(process, system.Memory(), j, im);
|
||||
ExportIndexedSymbolEntry ex;
|
||||
source.GetEntry(memory, im.index, ex);
|
||||
source.GetEntry(system.Memory(), im.index, ex);
|
||||
u32 symbol_address = source.SegmentTagToAddress(ex.symbol_position);
|
||||
LOG_TRACE(Service_LDR, " Imports 0x{:08X}", symbol_address);
|
||||
ResultCode result =
|
||||
|
@ -884,7 +886,7 @@ ResultCode CROHelper::ApplyModuleImport(VAddr crs_address) {
|
|||
ModuleName(), entry.import_anonymous_symbol_num, source.ModuleName());
|
||||
for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) {
|
||||
ImportAnonymousSymbolEntry im;
|
||||
entry.GetImportAnonymousSymbolEntry(process, memory, j, im);
|
||||
entry.GetImportAnonymousSymbolEntry(process, system.Memory(), j, im);
|
||||
u32 symbol_address = source.SegmentTagToAddress(im.symbol_position);
|
||||
LOG_TRACE(Service_LDR, " Imports 0x{:08X}", symbol_address);
|
||||
ResultCode result =
|
||||
|
@ -913,15 +915,15 @@ ResultCode CROHelper::ApplyExportNamedSymbol(CROHelper target) {
|
|||
u32 target_symbol_import_num = target.GetField(ImportNamedSymbolNum);
|
||||
for (u32 i = 0; i < target_symbol_import_num; ++i) {
|
||||
ImportNamedSymbolEntry entry;
|
||||
target.GetEntry(memory, i, entry);
|
||||
target.GetEntry(system.Memory(), i, entry);
|
||||
VAddr relocation_addr = entry.relocation_batch_offset;
|
||||
ExternalRelocationEntry relocation_entry;
|
||||
memory.ReadBlock(process, relocation_addr, &relocation_entry,
|
||||
sizeof(ExternalRelocationEntry));
|
||||
system.Memory().ReadBlock(process, relocation_addr, &relocation_entry,
|
||||
sizeof(ExternalRelocationEntry));
|
||||
|
||||
if (!relocation_entry.is_batch_resolved) {
|
||||
std::string symbol_name =
|
||||
memory.ReadCString(entry.name_offset, target_import_strings_size);
|
||||
system.Memory().ReadCString(entry.name_offset, target_import_strings_size);
|
||||
u32 symbol_address = FindExportNamedSymbol(symbol_name);
|
||||
if (symbol_address != 0) {
|
||||
LOG_TRACE(Service_LDR, " exports symbol \"{}\"", symbol_name);
|
||||
|
@ -944,15 +946,15 @@ ResultCode CROHelper::ResetExportNamedSymbol(CROHelper target) {
|
|||
u32 target_symbol_import_num = target.GetField(ImportNamedSymbolNum);
|
||||
for (u32 i = 0; i < target_symbol_import_num; ++i) {
|
||||
ImportNamedSymbolEntry entry;
|
||||
target.GetEntry(memory, i, entry);
|
||||
target.GetEntry(system.Memory(), i, entry);
|
||||
VAddr relocation_addr = entry.relocation_batch_offset;
|
||||
ExternalRelocationEntry relocation_entry;
|
||||
memory.ReadBlock(process, relocation_addr, &relocation_entry,
|
||||
sizeof(ExternalRelocationEntry));
|
||||
system.Memory().ReadBlock(process, relocation_addr, &relocation_entry,
|
||||
sizeof(ExternalRelocationEntry));
|
||||
|
||||
if (relocation_entry.is_batch_resolved) {
|
||||
std::string symbol_name =
|
||||
memory.ReadCString(entry.name_offset, target_import_strings_size);
|
||||
system.Memory().ReadCString(entry.name_offset, target_import_strings_size);
|
||||
u32 symbol_address = FindExportNamedSymbol(symbol_name);
|
||||
if (symbol_address != 0) {
|
||||
LOG_TRACE(Service_LDR, " unexports symbol \"{}\"", symbol_name);
|
||||
|
@ -974,18 +976,19 @@ ResultCode CROHelper::ApplyModuleExport(CROHelper target) {
|
|||
u32 target_import_module_num = target.GetField(ImportModuleNum);
|
||||
for (u32 i = 0; i < target_import_module_num; ++i) {
|
||||
ImportModuleEntry entry;
|
||||
target.GetEntry(memory, i, entry);
|
||||
target.GetEntry(system.Memory(), i, entry);
|
||||
|
||||
if (memory.ReadCString(entry.name_offset, target_import_string_size) != module_name)
|
||||
if (system.Memory().ReadCString(entry.name_offset, target_import_string_size) !=
|
||||
module_name)
|
||||
continue;
|
||||
|
||||
LOG_INFO(Service_LDR, "CRO \"{}\" exports {} indexed symbols to \"{}\"", module_name,
|
||||
entry.import_indexed_symbol_num, target.ModuleName());
|
||||
for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) {
|
||||
ImportIndexedSymbolEntry im;
|
||||
entry.GetImportIndexedSymbolEntry(process, memory, j, im);
|
||||
entry.GetImportIndexedSymbolEntry(process, system.Memory(), j, im);
|
||||
ExportIndexedSymbolEntry ex;
|
||||
GetEntry(memory, im.index, ex);
|
||||
GetEntry(system.Memory(), im.index, ex);
|
||||
u32 symbol_address = SegmentTagToAddress(ex.symbol_position);
|
||||
LOG_TRACE(Service_LDR, " exports symbol 0x{:08X}", symbol_address);
|
||||
ResultCode result =
|
||||
|
@ -1000,7 +1003,7 @@ ResultCode CROHelper::ApplyModuleExport(CROHelper target) {
|
|||
entry.import_anonymous_symbol_num, target.ModuleName());
|
||||
for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) {
|
||||
ImportAnonymousSymbolEntry im;
|
||||
entry.GetImportAnonymousSymbolEntry(process, memory, j, im);
|
||||
entry.GetImportAnonymousSymbolEntry(process, system.Memory(), j, im);
|
||||
u32 symbol_address = SegmentTagToAddress(im.symbol_position);
|
||||
LOG_TRACE(Service_LDR, " exports symbol 0x{:08X}", symbol_address);
|
||||
ResultCode result =
|
||||
|
@ -1023,16 +1026,17 @@ ResultCode CROHelper::ResetModuleExport(CROHelper target) {
|
|||
u32 target_import_module_num = target.GetField(ImportModuleNum);
|
||||
for (u32 i = 0; i < target_import_module_num; ++i) {
|
||||
ImportModuleEntry entry;
|
||||
target.GetEntry(memory, i, entry);
|
||||
target.GetEntry(system.Memory(), i, entry);
|
||||
|
||||
if (memory.ReadCString(entry.name_offset, target_import_string_size) != module_name)
|
||||
if (system.Memory().ReadCString(entry.name_offset, target_import_string_size) !=
|
||||
module_name)
|
||||
continue;
|
||||
|
||||
LOG_DEBUG(Service_LDR, "CRO \"{}\" unexports indexed symbols to \"{}\"", module_name,
|
||||
target.ModuleName());
|
||||
for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) {
|
||||
ImportIndexedSymbolEntry im;
|
||||
entry.GetImportIndexedSymbolEntry(process, memory, j, im);
|
||||
entry.GetImportIndexedSymbolEntry(process, system.Memory(), j, im);
|
||||
ResultCode result =
|
||||
target.ApplyRelocationBatch(im.relocation_batch_offset, unresolved_symbol, true);
|
||||
if (result.IsError()) {
|
||||
|
@ -1045,7 +1049,7 @@ ResultCode CROHelper::ResetModuleExport(CROHelper target) {
|
|||
target.ModuleName());
|
||||
for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) {
|
||||
ImportAnonymousSymbolEntry im;
|
||||
entry.GetImportAnonymousSymbolEntry(process, memory, j, im);
|
||||
entry.GetImportAnonymousSymbolEntry(process, system.Memory(), j, im);
|
||||
ResultCode result =
|
||||
target.ApplyRelocationBatch(im.relocation_batch_offset, unresolved_symbol, true);
|
||||
if (result.IsError()) {
|
||||
|
@ -1063,15 +1067,16 @@ ResultCode CROHelper::ApplyExitRelocations(VAddr crs_address) {
|
|||
u32 symbol_import_num = GetField(ImportNamedSymbolNum);
|
||||
for (u32 i = 0; i < symbol_import_num; ++i) {
|
||||
ImportNamedSymbolEntry entry;
|
||||
GetEntry(memory, i, entry);
|
||||
GetEntry(system.Memory(), i, entry);
|
||||
VAddr relocation_addr = entry.relocation_batch_offset;
|
||||
ExternalRelocationEntry relocation_entry;
|
||||
memory.ReadBlock(process, relocation_addr, &relocation_entry,
|
||||
sizeof(ExternalRelocationEntry));
|
||||
system.Memory().ReadBlock(process, relocation_addr, &relocation_entry,
|
||||
sizeof(ExternalRelocationEntry));
|
||||
|
||||
if (memory.ReadCString(entry.name_offset, import_strings_size) == "__aeabi_atexit") {
|
||||
if (system.Memory().ReadCString(entry.name_offset, import_strings_size) ==
|
||||
"__aeabi_atexit") {
|
||||
ResultCode result = ForEachAutoLinkCRO(
|
||||
process, memory, cpu, crs_address, [&](CROHelper source) -> ResultVal<bool> {
|
||||
process, system, crs_address, [&](CROHelper source) -> ResultVal<bool> {
|
||||
u32 symbol_address = source.FindExportNamedSymbol("nnroAeabiAtexit_");
|
||||
|
||||
if (symbol_address != 0) {
|
||||
|
@ -1126,7 +1131,8 @@ ResultCode CROHelper::Rebase(VAddr crs_address, u32 cro_size, VAddr data_segment
|
|||
return result;
|
||||
}
|
||||
|
||||
result = VerifyStringTableLength(memory, GetField(ModuleNameOffset), GetField(ModuleNameSize));
|
||||
result = VerifyStringTableLength(system.Memory(), GetField(ModuleNameOffset),
|
||||
GetField(ModuleNameSize));
|
||||
if (result.IsError()) {
|
||||
LOG_ERROR(Service_LDR, "Error verifying module name {:08X}", result.raw);
|
||||
return result;
|
||||
|
@ -1155,8 +1161,8 @@ ResultCode CROHelper::Rebase(VAddr crs_address, u32 cro_size, VAddr data_segment
|
|||
return result;
|
||||
}
|
||||
|
||||
result =
|
||||
VerifyStringTableLength(memory, GetField(ExportStringsOffset), GetField(ExportStringsSize));
|
||||
result = VerifyStringTableLength(system.Memory(), GetField(ExportStringsOffset),
|
||||
GetField(ExportStringsSize));
|
||||
if (result.IsError()) {
|
||||
LOG_ERROR(Service_LDR, "Error verifying export strings {:08X}", result.raw);
|
||||
return result;
|
||||
|
@ -1192,8 +1198,8 @@ ResultCode CROHelper::Rebase(VAddr crs_address, u32 cro_size, VAddr data_segment
|
|||
return result;
|
||||
}
|
||||
|
||||
result =
|
||||
VerifyStringTableLength(memory, GetField(ImportStringsOffset), GetField(ImportStringsSize));
|
||||
result = VerifyStringTableLength(system.Memory(), GetField(ImportStringsOffset),
|
||||
GetField(ImportStringsSize));
|
||||
if (result.IsError()) {
|
||||
LOG_ERROR(Service_LDR, "Error verifying import strings {:08X}", result.raw);
|
||||
return result;
|
||||
|
@ -1266,11 +1272,11 @@ ResultCode CROHelper::Link(VAddr crs_address, bool link_on_load_bug_fix) {
|
|||
// so we do the same
|
||||
if (GetField(SegmentNum) >= 2) { // means we have .data segment
|
||||
SegmentEntry entry;
|
||||
GetEntry(memory, 2, entry);
|
||||
GetEntry(system.Memory(), 2, entry);
|
||||
ASSERT(entry.type == SegmentType::Data);
|
||||
data_segment_address = entry.offset;
|
||||
entry.offset = GetField(DataOffset);
|
||||
SetEntry(memory, 2, entry);
|
||||
SetEntry(system.Memory(), 2, entry);
|
||||
}
|
||||
}
|
||||
SCOPE_EXIT({
|
||||
|
@ -1278,9 +1284,9 @@ ResultCode CROHelper::Link(VAddr crs_address, bool link_on_load_bug_fix) {
|
|||
if (link_on_load_bug_fix) {
|
||||
if (GetField(SegmentNum) >= 2) {
|
||||
SegmentEntry entry;
|
||||
GetEntry(memory, 2, entry);
|
||||
GetEntry(system.Memory(), 2, entry);
|
||||
entry.offset = data_segment_address;
|
||||
SetEntry(memory, 2, entry);
|
||||
SetEntry(system.Memory(), 2, entry);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1301,7 +1307,7 @@ ResultCode CROHelper::Link(VAddr crs_address, bool link_on_load_bug_fix) {
|
|||
}
|
||||
|
||||
// Exports symbols to other modules
|
||||
result = ForEachAutoLinkCRO(process, memory, cpu, crs_address,
|
||||
result = ForEachAutoLinkCRO(process, system, crs_address,
|
||||
[this](CROHelper target) -> ResultVal<bool> {
|
||||
ResultCode result = ApplyExportNamedSymbol(target);
|
||||
if (result.IsError())
|
||||
|
@ -1346,7 +1352,7 @@ ResultCode CROHelper::Unlink(VAddr crs_address) {
|
|||
|
||||
// Resets all symbols in other modules imported from this module
|
||||
// Note: the RO service seems only searching in auto-link modules
|
||||
result = ForEachAutoLinkCRO(process, memory, cpu, crs_address,
|
||||
result = ForEachAutoLinkCRO(process, system, crs_address,
|
||||
[this](CROHelper target) -> ResultVal<bool> {
|
||||
ResultCode result = ResetExportNamedSymbol(target);
|
||||
if (result.IsError())
|
||||
|
@ -1387,13 +1393,13 @@ void CROHelper::InitCRS() {
|
|||
}
|
||||
|
||||
void CROHelper::Register(VAddr crs_address, bool auto_link) {
|
||||
CROHelper crs(crs_address, process, memory, cpu);
|
||||
CROHelper head(auto_link ? crs.NextModule() : crs.PreviousModule(), process, memory, cpu);
|
||||
CROHelper crs(crs_address, process, system);
|
||||
CROHelper head(auto_link ? crs.NextModule() : crs.PreviousModule(), process, system);
|
||||
|
||||
if (head.module_address) {
|
||||
// there are already CROs registered
|
||||
// register as the new tail
|
||||
CROHelper tail(head.PreviousModule(), process, memory, cpu);
|
||||
CROHelper tail(head.PreviousModule(), process, system);
|
||||
|
||||
// link with the old tail
|
||||
ASSERT(tail.NextModule() == 0);
|
||||
|
@ -1419,11 +1425,11 @@ void CROHelper::Register(VAddr crs_address, bool auto_link) {
|
|||
}
|
||||
|
||||
void CROHelper::Unregister(VAddr crs_address) {
|
||||
CROHelper crs(crs_address, process, memory, cpu);
|
||||
CROHelper next_head(crs.NextModule(), process, memory, cpu);
|
||||
CROHelper previous_head(crs.PreviousModule(), process, memory, cpu);
|
||||
CROHelper next(NextModule(), process, memory, cpu);
|
||||
CROHelper previous(PreviousModule(), process, memory, cpu);
|
||||
CROHelper crs(crs_address, process, system);
|
||||
CROHelper next_head(crs.NextModule(), process, system);
|
||||
CROHelper previous_head(crs.PreviousModule(), process, system);
|
||||
CROHelper next(NextModule(), process, system);
|
||||
CROHelper previous(PreviousModule(), process, system);
|
||||
|
||||
if (module_address == next_head.module_address ||
|
||||
module_address == previous_head.module_address) {
|
||||
|
@ -1517,7 +1523,7 @@ std::tuple<VAddr, u32> CROHelper::GetExecutablePages() const {
|
|||
u32 segment_num = GetField(SegmentNum);
|
||||
for (u32 i = 0; i < segment_num; ++i) {
|
||||
SegmentEntry entry;
|
||||
GetEntry(memory, i, entry);
|
||||
GetEntry(system.Memory(), i, entry);
|
||||
if (entry.type == SegmentType::Code && entry.size != 0) {
|
||||
VAddr begin = Common::AlignDown(entry.offset, Memory::PAGE_SIZE);
|
||||
VAddr end = Common::AlignUp(entry.offset + entry.size, Memory::PAGE_SIZE);
|
||||
|
|
|
@ -33,12 +33,11 @@ static constexpr u32 CRO_HASH_SIZE = 0x80;
|
|||
class CROHelper final {
|
||||
public:
|
||||
// TODO (wwylele): pass in the process handle for memory access
|
||||
explicit CROHelper(VAddr cro_address, Kernel::Process& process, Memory::MemorySystem& memory,
|
||||
ARM_Interface& cpu)
|
||||
: module_address(cro_address), process(process), memory(memory), cpu(cpu) {}
|
||||
explicit CROHelper(VAddr cro_address, Kernel::Process& process, Core::System& system)
|
||||
: module_address(cro_address), process(process), system(system) {}
|
||||
|
||||
std::string ModuleName() const {
|
||||
return memory.ReadCString(GetField(ModuleNameOffset), GetField(ModuleNameSize));
|
||||
return system.Memory().ReadCString(GetField(ModuleNameOffset), GetField(ModuleNameSize));
|
||||
}
|
||||
|
||||
u32 GetFileSize() const {
|
||||
|
@ -144,8 +143,7 @@ public:
|
|||
private:
|
||||
const VAddr module_address; ///< the virtual address of this module
|
||||
Kernel::Process& process; ///< the owner process of this module
|
||||
Memory::MemorySystem& memory;
|
||||
ARM_Interface& cpu;
|
||||
Core::System& system;
|
||||
|
||||
/**
|
||||
* Each item in this enum represents a u32 field in the header begin from address+0x80,
|
||||
|
@ -403,11 +401,11 @@ private:
|
|||
}
|
||||
|
||||
u32 GetField(HeaderField field) const {
|
||||
return memory.Read32(Field(field));
|
||||
return system.Memory().Read32(Field(field));
|
||||
}
|
||||
|
||||
void SetField(HeaderField field, u32 value) {
|
||||
memory.Write32(Field(field), value);
|
||||
system.Memory().Write32(Field(field), value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -474,12 +472,11 @@ private:
|
|||
* otherwise error code of the last iteration.
|
||||
*/
|
||||
template <typename FunctionObject>
|
||||
static ResultCode ForEachAutoLinkCRO(Kernel::Process& process, Memory::MemorySystem& memory,
|
||||
ARM_Interface& cpu, VAddr crs_address,
|
||||
FunctionObject func) {
|
||||
static ResultCode ForEachAutoLinkCRO(Kernel::Process& process, Core::System& system,
|
||||
VAddr crs_address, FunctionObject func) {
|
||||
VAddr current = crs_address;
|
||||
while (current != 0) {
|
||||
CROHelper cro(current, process, memory, cpu);
|
||||
CROHelper cro(current, process, system);
|
||||
CASCADE_RESULT(bool next, func(cro));
|
||||
if (!next)
|
||||
break;
|
||||
|
|
|
@ -120,7 +120,7 @@ void RO::Initialize(Kernel::HLERequestContext& ctx) {
|
|||
return;
|
||||
}
|
||||
|
||||
CROHelper crs(crs_address, *process, system.Memory(), system.CPU());
|
||||
CROHelper crs(crs_address, *process, system);
|
||||
crs.InitCRS();
|
||||
|
||||
result = crs.Rebase(0, crs_size, 0, 0, 0, 0, true);
|
||||
|
@ -254,7 +254,7 @@ void RO::LoadCRO(Kernel::HLERequestContext& ctx, bool link_on_load_bug_fix) {
|
|||
return;
|
||||
}
|
||||
|
||||
CROHelper cro(cro_address, *process, system.Memory(), system.CPU());
|
||||
CROHelper cro(cro_address, *process, system);
|
||||
|
||||
result = cro.VerifyHash(cro_size, crr_address);
|
||||
if (result.IsError()) {
|
||||
|
@ -318,7 +318,7 @@ void RO::LoadCRO(Kernel::HLERequestContext& ctx, bool link_on_load_bug_fix) {
|
|||
}
|
||||
}
|
||||
|
||||
system.CPU().InvalidateCacheRange(cro_address, cro_size);
|
||||
system.InvalidateCacheRange(cro_address, cro_size);
|
||||
|
||||
LOG_INFO(Service_LDR, "CRO \"{}\" loaded at 0x{:08X}, fixed_end=0x{:08X}", cro.ModuleName(),
|
||||
cro_address, cro_address + fix_size);
|
||||
|
@ -336,7 +336,7 @@ void RO::UnloadCRO(Kernel::HLERequestContext& ctx) {
|
|||
LOG_DEBUG(Service_LDR, "called, cro_address=0x{:08X}, zero={}, cro_buffer_ptr=0x{:08X}",
|
||||
cro_address, zero, cro_buffer_ptr);
|
||||
|
||||
CROHelper cro(cro_address, *process, system.Memory(), system.CPU());
|
||||
CROHelper cro(cro_address, *process, system);
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
|
||||
|
@ -391,7 +391,7 @@ void RO::UnloadCRO(Kernel::HLERequestContext& ctx) {
|
|||
LOG_ERROR(Service_LDR, "Error unmapping CRO {:08X}", result.raw);
|
||||
}
|
||||
|
||||
system.CPU().InvalidateCacheRange(cro_address, fixed_size);
|
||||
system.InvalidateCacheRange(cro_address, fixed_size);
|
||||
|
||||
rb.Push(result);
|
||||
}
|
||||
|
@ -403,7 +403,7 @@ void RO::LinkCRO(Kernel::HLERequestContext& ctx) {
|
|||
|
||||
LOG_DEBUG(Service_LDR, "called, cro_address=0x{:08X}", cro_address);
|
||||
|
||||
CROHelper cro(cro_address, *process, system.Memory(), system.CPU());
|
||||
CROHelper cro(cro_address, *process, system);
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
|
||||
|
@ -443,7 +443,7 @@ void RO::UnlinkCRO(Kernel::HLERequestContext& ctx) {
|
|||
|
||||
LOG_DEBUG(Service_LDR, "called, cro_address=0x{:08X}", cro_address);
|
||||
|
||||
CROHelper cro(cro_address, *process, system.Memory(), system.CPU());
|
||||
CROHelper cro(cro_address, *process, system);
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
|
||||
|
@ -492,7 +492,7 @@ void RO::Shutdown(Kernel::HLERequestContext& ctx) {
|
|||
return;
|
||||
}
|
||||
|
||||
CROHelper crs(slot->loaded_crs, *process, system.Memory(), system.CPU());
|
||||
CROHelper crs(slot->loaded_crs, *process, system);
|
||||
crs.Unrebase(true);
|
||||
|
||||
ResultCode result = RESULT_SUCCESS;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue