From 15ff64e03a377e132ec5e4d62ceca6e6b2b4eb73 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 29 Sep 2021 13:42:11 -0700 Subject: [PATCH] os: implement ExpandUnsignedValueToAscii Nintendo does this as of latest firmware. It's desirable because it removes the only usage of util::SNPrintf() from os library, which means programs which don't otherwise use SNPrintf do not need to link it into .text. This saves ~0xD40 of .text as of time-of-commit when successfully unlinking, and e.g. reduces our sm (and other modules) memory size by a page. --- .../source/os/impl/os_thread_manager.cpp | 4 +- .../source/os/impl/os_utility.cpp | 42 +++++++++++++++++++ .../source/os/impl/os_utility.hpp | 24 +++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 libraries/libstratosphere/source/os/impl/os_utility.cpp create mode 100644 libraries/libstratosphere/source/os/impl/os_utility.hpp diff --git a/libraries/libstratosphere/source/os/impl/os_thread_manager.cpp b/libraries/libstratosphere/source/os/impl/os_thread_manager.cpp index b83d2b771..e6c456a75 100644 --- a/libraries/libstratosphere/source/os/impl/os_thread_manager.cpp +++ b/libraries/libstratosphere/source/os/impl/os_thread_manager.cpp @@ -19,6 +19,7 @@ #include "os_waitable_holder_base.hpp" #include "os_waitable_holder_impl.hpp" #include "os_waitable_object_list.hpp" +#include "os_utility.hpp" namespace ams::os::impl { @@ -223,7 +224,8 @@ namespace ams::os::impl { constexpr size_t ThreadNamePrefixSize = sizeof(ThreadNamePrefix) - 1; const u64 func = reinterpret_cast(thread->function); static_assert(ThreadNamePrefixSize + sizeof(func) * 2 + 1 <= sizeof(thread->name_buffer)); - util::SNPrintf(thread->name_buffer, sizeof(thread->name_buffer), "%s%016lX", ThreadNamePrefix, func); + std::memcpy(thread->name_buffer, ThreadNamePrefix, ThreadNamePrefixSize); + os::impl::ExpandUnsignedValueToAscii(thread->name_buffer + ThreadNamePrefixSize, func); } thread->name_pointer = thread->name_buffer; diff --git a/libraries/libstratosphere/source/os/impl/os_utility.cpp b/libraries/libstratosphere/source/os/impl/os_utility.cpp new file mode 100644 index 000000000..3a0f709f9 --- /dev/null +++ b/libraries/libstratosphere/source/os/impl/os_utility.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "os_utility.hpp" + +namespace ams::os::impl { + + void ExpandUnsignedValueToAscii(char *dst, u64 value) { + /* Determine size needed. */ + constexpr size_t SizeNeeded = (BITSIZEOF(value) / 4) * sizeof(char); + + /* Write null-terminator. */ + dst[SizeNeeded] = '\x00'; + + /* Write characters. */ + for (size_t i = 0; i < SizeNeeded; ++i) { + /* Determine current character. */ + const auto nybble = (value & 0xF); + const char cur_c = (nybble < 10) ? ('0' + nybble) : ('A' + nybble - 10); + + /* Write current character. */ + dst[SizeNeeded - 1 - i] = cur_c; + + /* Shift to next nybble. */ + value >>= 4; + } + } + +} diff --git a/libraries/libstratosphere/source/os/impl/os_utility.hpp b/libraries/libstratosphere/source/os/impl/os_utility.hpp new file mode 100644 index 000000000..bbbd9aeeb --- /dev/null +++ b/libraries/libstratosphere/source/os/impl/os_utility.hpp @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include "os_waitable_holder_base.hpp" +#include "os_waitable_manager_impl.hpp" + +namespace ams::os::impl { + + void ExpandUnsignedValueToAscii(char *dst, u64 value); + +}