mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2026-06-25 05:05:52 +00:00
loader: add non-release build debug logging
This commit is contained in:
parent
fbeea26919
commit
94e62a7b1b
@ -219,7 +219,7 @@ namespace ams::ldr {
|
|||||||
/* Read NSO header. */
|
/* Read NSO header. */
|
||||||
size_t read_size;
|
size_t read_size;
|
||||||
R_TRY(fs::ReadFile(std::addressof(read_size), file, 0, g_nso_headers + ctx.nso_count, sizeof(NsoHeader)));
|
R_TRY(fs::ReadFile(std::addressof(read_size), file, 0, g_nso_headers + ctx.nso_count, sizeof(NsoHeader)));
|
||||||
R_UNLESS(read_size == sizeof(NsoHeader), ldr::ResultInvalidNso());
|
R_UNLESS_LOG(read_size == sizeof(NsoHeader), ldr::ResultInvalidNso(), "[ldr] NSO header truncated!\n");
|
||||||
|
|
||||||
/* Note nso is present. */
|
/* Note nso is present. */
|
||||||
switch (i) {
|
switch (i) {
|
||||||
@ -258,7 +258,7 @@ namespace ams::ldr {
|
|||||||
|
|
||||||
Result CheckAutoLoad(const AutoLoadModuleContext &ctx, u32 acid_flags) {
|
Result CheckAutoLoad(const AutoLoadModuleContext &ctx, u32 acid_flags) {
|
||||||
/* We must always have a main. */
|
/* We must always have a main. */
|
||||||
R_UNLESS(ctx.ali.has_main, ldr::ResultInvalidNso());
|
R_UNLESS_LOG(ctx.ali.has_main, ldr::ResultInvalidNso(), "[ldr] Missing main!\n");
|
||||||
|
|
||||||
/* Validate flags and extents for all present NSOs. */
|
/* Validate flags and extents for all present NSOs. */
|
||||||
for (int i = 0; i < ctx.nso_count; ++i) {
|
for (int i = 0; i < ctx.nso_count; ++i) {
|
||||||
@ -266,11 +266,11 @@ namespace ams::ldr {
|
|||||||
|
|
||||||
/* All NSOs must not be --X. */
|
/* All NSOs must not be --X. */
|
||||||
/* This is "probably" not checked on Ounce? */
|
/* This is "probably" not checked on Ounce? */
|
||||||
R_UNLESS((hdr.flags & NsoHeader::Flag_PreventCodeReads) == 0, ldr::ResultInvalidNso());
|
R_UNLESS_LOG((hdr.flags & NsoHeader::Flag_PreventCodeReads) == 0, ldr::ResultInvalidNso(), "[ldr] NSO[%d] --x not allowed!\n", i);
|
||||||
|
|
||||||
/* Zstd compression only allowed on main, and only when both rtld+sdk are present. */
|
/* Zstd compression only allowed on main, and only when both rtld+sdk are present. */
|
||||||
if (i != ctx.main_nso_idx || ctx.rtld_idx < 0 || ctx.sdk_nso_idx < 0) {
|
if (i != ctx.main_nso_idx || ctx.rtld_idx < 0 || ctx.sdk_nso_idx < 0) {
|
||||||
R_UNLESS((hdr.flags & NsoHeader::Flag_UseZbicCompression) == 0, ldr::ResultInvalidNso());
|
R_UNLESS_LOG((hdr.flags & NsoHeader::Flag_UseZbicCompression) == 0, ldr::ResultInvalidNso(), "[ldr] NSO[%d] zbic not allowed!\n", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NSOs must have page-aligned segments. */
|
/* NSOs must have page-aligned segments. */
|
||||||
@ -293,13 +293,13 @@ namespace ams::ldr {
|
|||||||
const bool has_browser_dll = (acid_flags & Acid::AcidFlag_LoadBrowserCoreDll) != 0;
|
const bool has_browser_dll = (acid_flags & Acid::AcidFlag_LoadBrowserCoreDll) != 0;
|
||||||
if (ctx.ali.has_rtld || ctx.ali.has_sdk) {
|
if (ctx.ali.has_rtld || ctx.ali.has_sdk) {
|
||||||
/* If we have sdk we must have rtld. */
|
/* If we have sdk we must have rtld. */
|
||||||
R_UNLESS(ctx.ali.has_rtld, ldr::ResultInvalidNso());
|
R_UNLESS_LOG(ctx.ali.has_rtld, ldr::ResultInvalidNso(), "[ldr] Missing rtld!\n");
|
||||||
|
|
||||||
/* If we have rtld, we must not have browser core dll. */
|
/* If we have rtld, we must not have browser core dll. */
|
||||||
R_UNLESS(!has_browser_dll, ldr::ResultInvalidNso());
|
R_UNLESS_LOG(!has_browser_dll, ldr::ResultInvalidNso(), "[ldr] BrowserCoreDll must not be present!\n");
|
||||||
} else {
|
} else {
|
||||||
/* We must not have both subsdk and browser dll. */
|
/* We must not have both subsdk and browser dll. */
|
||||||
R_UNLESS(!(ctx.ali.has_subsdk && has_browser_dll), ldr::ResultInvalidNso());
|
R_UNLESS_LOG(!(ctx.ali.has_subsdk && has_browser_dll), ldr::ResultInvalidNso(), "[ldr] Can't have both subsdk and BrowserCoreDll!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
@ -384,6 +384,8 @@ namespace ams::ldr {
|
|||||||
|
|
||||||
/* If the signature check fails, we need to check if this is allowable. */
|
/* If the signature check fails, we need to check if this is allowable. */
|
||||||
if (!is_signature_valid) {
|
if (!is_signature_valid) {
|
||||||
|
AMS_LOG("[ldr] invalid signature!\n");
|
||||||
|
|
||||||
/* We have to enforce signature checks on prod and when we have a signature to check on dev. */
|
/* We have to enforce signature checks on prod and when we have a signature to check on dev. */
|
||||||
R_UNLESS(IsDevelopmentForAcidProductionCheck(), ldr::ResultInvalidNcaSignature());
|
R_UNLESS(IsDevelopmentForAcidProductionCheck(), ldr::ResultInvalidNcaSignature());
|
||||||
R_UNLESS(!code_verification_data.has_data, ldr::ResultInvalidNcaSignature());
|
R_UNLESS(!code_verification_data.has_data, ldr::ResultInvalidNcaSignature());
|
||||||
@ -634,10 +636,13 @@ namespace ams::ldr {
|
|||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result LoadAutoLoadModuleSegment(fs::FileHandle file, size_t file_offset, size_t compressed_size, size_t segment_size, bool is_compressed, bool is_zstd, uintptr_t map_base, uintptr_t map_end) {
|
Result LoadAutoLoadModuleSegment(fs::FileHandle file, size_t file_offset, size_t compressed_size, size_t segment_size, bool is_compressed, bool is_zbic, uintptr_t map_base, uintptr_t map_end) {
|
||||||
/* Select read size based on compression. */
|
/* Select read size based on compression. */
|
||||||
size_t file_size = is_compressed ? compressed_size : segment_size;
|
size_t file_size = is_compressed ? compressed_size : segment_size;
|
||||||
|
|
||||||
|
AMS_LOG("[ldr] Loading segment @ 0x%016lx: compressed=%d, file_size=0x%08lx, compressed_size=0x%08lx, segment_size=0x%08lx\n",
|
||||||
|
map_base, is_compressed, file_size, compressed_size, segment_size);
|
||||||
|
|
||||||
/* Validate size. */
|
/* Validate size. */
|
||||||
R_UNLESS(file_size <= segment_size, ldr::ResultInvalidNso());
|
R_UNLESS(file_size <= segment_size, ldr::ResultInvalidNso());
|
||||||
R_UNLESS(file_size <= std::numeric_limits<s32>::max(), ldr::ResultInvalidNso());
|
R_UNLESS(file_size <= std::numeric_limits<s32>::max(), ldr::ResultInvalidNso());
|
||||||
@ -647,19 +652,19 @@ namespace ams::ldr {
|
|||||||
uintptr_t load_address = is_compressed ? map_end - compressed_size : map_base;
|
uintptr_t load_address = is_compressed ? map_end - compressed_size : map_base;
|
||||||
size_t read_size;
|
size_t read_size;
|
||||||
R_TRY(fs::ReadFile(std::addressof(read_size), file, file_offset, reinterpret_cast<void *>(load_address), file_size));
|
R_TRY(fs::ReadFile(std::addressof(read_size), file, file_offset, reinterpret_cast<void *>(load_address), file_size));
|
||||||
R_UNLESS(read_size == file_size, ldr::ResultInvalidNso());
|
R_UNLESS_LOG(read_size == file_size, ldr::ResultInvalidNso(), "[ldr] Couldn't read segment from file!\n");
|
||||||
|
|
||||||
/* Uncompress if necessary. */
|
/* Uncompress if necessary. */
|
||||||
R_SUCCEED_IF(!is_compressed);
|
R_SUCCEED_IF(!is_compressed);
|
||||||
|
|
||||||
auto compressed_data_buf = reinterpret_cast<const void *>(load_address);
|
auto compressed_data_buf = reinterpret_cast<const void *>(load_address);
|
||||||
|
|
||||||
if (is_zstd) {
|
if (is_zbic) {
|
||||||
bool decompressed = util::DecompressZbicForLoader(reinterpret_cast<void *>(g_zstd_dctx_workspace), sizeof(g_zstd_dctx_workspace), reinterpret_cast<void *>(map_base), static_cast<size_t>(map_end - map_base), segment_size, compressed_data_buf, file_size);
|
bool decompressed = util::DecompressZbicForLoader(reinterpret_cast<void *>(g_zstd_dctx_workspace), sizeof(g_zstd_dctx_workspace), reinterpret_cast<void *>(map_base), static_cast<size_t>(map_end - map_base), segment_size, compressed_data_buf, file_size);
|
||||||
R_UNLESS(decompressed, ldr::ResultInvalidNso());
|
R_UNLESS_LOG(decompressed, ldr::ResultInvalidNso(), "[ldr] Failed to decompress segment with zbic!\n");
|
||||||
} else {
|
} else {
|
||||||
bool decompressed = (util::DecompressLZ4(reinterpret_cast<void *>(map_base), segment_size, compressed_data_buf, file_size) == static_cast<int>(segment_size));
|
bool decompressed = (util::DecompressLZ4(reinterpret_cast<void *>(map_base), segment_size, compressed_data_buf, file_size) == static_cast<int>(segment_size));
|
||||||
R_UNLESS(decompressed, ldr::ResultInvalidNso());
|
R_UNLESS_LOG(decompressed, ldr::ResultInvalidNso(), "[ldr] Failed to decompress segment with lz4!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
@ -674,12 +679,12 @@ namespace ams::ldr {
|
|||||||
crypto::GenerateSha256(hash, sizeof(hash),
|
crypto::GenerateSha256(hash, sizeof(hash),
|
||||||
reinterpret_cast<void *>(map_address + nso_header->segments[segment].dst_offset),
|
reinterpret_cast<void *>(map_address + nso_header->segments[segment].dst_offset),
|
||||||
nso_header->segments[segment].size);
|
nso_header->segments[segment].size);
|
||||||
R_UNLESS(std::memcmp(hash, nso_header->segment_hashes[segment], sizeof(hash)) == 0, ldr::ResultInvalidNso());
|
R_UNLESS_LOG(std::memcmp(hash, nso_header->segment_hashes[segment], sizeof(hash)) == 0, ldr::ResultInvalidNso(), "[ldr] Invalid segment hash!\n");
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result LoadAutoLoadModule(os::NativeHandle process_handle, fs::FileHandle file, const NsoHeader *nso_header, uintptr_t nso_address, size_t nso_size, size_t map_size) {
|
Result LoadAutoLoadModule(os::NativeHandle process_handle, fs::FileHandle file, const NsoHeader *nso_header, uintptr_t nso_address, size_t nso_size, size_t map_size) {
|
||||||
const bool is_zstd = (nso_header->flags & NsoHeader::Flag_UseZbicCompression) != 0;
|
const bool is_zbic = (nso_header->flags & NsoHeader::Flag_UseZbicCompression) != 0;
|
||||||
|
|
||||||
/* Map and read data from file. */
|
/* Map and read data from file. */
|
||||||
{
|
{
|
||||||
@ -693,11 +698,11 @@ namespace ams::ldr {
|
|||||||
|
|
||||||
/* Load NSO segments. */
|
/* Load NSO segments. */
|
||||||
R_TRY(LoadAutoLoadModuleSegment(file, nso_header->segments[NsoHeader::Segment_Text].file_offset, nso_header->text_compressed_size, nso_header->text_size,
|
R_TRY(LoadAutoLoadModuleSegment(file, nso_header->segments[NsoHeader::Segment_Text].file_offset, nso_header->text_compressed_size, nso_header->text_size,
|
||||||
(nso_header->flags & NsoHeader::Flag_CompressedText) != 0, is_zstd, map_address + nso_header->text_dst_offset, map_end));
|
(nso_header->flags & NsoHeader::Flag_CompressedText) != 0, is_zbic, map_address + nso_header->text_dst_offset, map_end));
|
||||||
R_TRY(LoadAutoLoadModuleSegment(file, nso_header->segments[NsoHeader::Segment_Ro].file_offset, nso_header->ro_compressed_size, nso_header->ro_size,
|
R_TRY(LoadAutoLoadModuleSegment(file, nso_header->segments[NsoHeader::Segment_Ro].file_offset, nso_header->ro_compressed_size, nso_header->ro_size,
|
||||||
(nso_header->flags & NsoHeader::Flag_CompressedRo) != 0, is_zstd, map_address + nso_header->ro_dst_offset, map_end));
|
(nso_header->flags & NsoHeader::Flag_CompressedRo) != 0, is_zbic, map_address + nso_header->ro_dst_offset, map_end));
|
||||||
R_TRY(LoadAutoLoadModuleSegment(file, nso_header->segments[NsoHeader::Segment_Rw].file_offset, nso_header->rw_compressed_size, nso_header->rw_size,
|
R_TRY(LoadAutoLoadModuleSegment(file, nso_header->segments[NsoHeader::Segment_Rw].file_offset, nso_header->rw_compressed_size, nso_header->rw_size,
|
||||||
(nso_header->flags & NsoHeader::Flag_CompressedRw) != 0, is_zstd, map_address + nso_header->rw_dst_offset, map_end));
|
(nso_header->flags & NsoHeader::Flag_CompressedRw) != 0, is_zbic, map_address + nso_header->rw_dst_offset, map_end));
|
||||||
|
|
||||||
/* Clear unused space to zero. */
|
/* Clear unused space to zero. */
|
||||||
const size_t text_end = static_cast<size_t>(nso_header->text_dst_offset) + static_cast<size_t>(nso_header->text_size);
|
const size_t text_end = static_cast<size_t>(nso_header->text_dst_offset) + static_cast<size_t>(nso_header->text_size);
|
||||||
@ -743,14 +748,15 @@ namespace ams::ldr {
|
|||||||
|
|
||||||
for (int i = 0; i < ctx.nso_count; i++) {
|
for (int i = 0; i < ctx.nso_count; i++) {
|
||||||
const NsoIndex nso_idx = static_cast<NsoIndex>(ctx.ali.nso_indices[i]);
|
const NsoIndex nso_idx = static_cast<NsoIndex>(ctx.ali.nso_indices[i]);
|
||||||
|
const bool is_zbic = (ctx.headers[i].flags & NsoHeader::Flag_UseZbicCompression) != 0;
|
||||||
|
const size_t map_size = is_zbic ? (total_end - process_info->nso_address[i]) : process_info->nso_size[i];
|
||||||
|
|
||||||
|
AMS_LOG("[ldr] module[%d]: idx=%d, path='%s', zbic=%d\n", i, (int)nso_idx, GetNsoPath(nso_idx), is_zbic);
|
||||||
|
|
||||||
fs::FileHandle file;
|
fs::FileHandle file;
|
||||||
R_TRY(fs::OpenFile(std::addressof(file), GetNsoPath(nso_idx), fs::OpenMode_Read));
|
R_TRY(fs::OpenFile(std::addressof(file), GetNsoPath(nso_idx), fs::OpenMode_Read));
|
||||||
ON_SCOPE_EXIT { fs::CloseFile(file); };
|
ON_SCOPE_EXIT { fs::CloseFile(file); };
|
||||||
|
|
||||||
const bool is_zstd = (ctx.headers[i].flags & NsoHeader::Flag_UseZbicCompression) != 0;
|
|
||||||
const size_t map_size = is_zstd ? (total_end - process_info->nso_address[i]) : process_info->nso_size[i];
|
|
||||||
|
|
||||||
R_TRY(LoadAutoLoadModule(process_info->process_handle, file, ctx.headers + i,
|
R_TRY(LoadAutoLoadModule(process_info->process_handle, file, ctx.headers + i,
|
||||||
process_info->nso_address[i], process_info->nso_size[i], map_size));
|
process_info->nso_address[i], process_info->nso_size[i], map_size));
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user