diff --git a/thermosphere/Makefile b/thermosphere/Makefile index 7fdb177d8..4b312e2b1 100644 --- a/thermosphere/Makefile +++ b/thermosphere/Makefile @@ -9,6 +9,8 @@ endif TOPDIR ?= $(CURDIR) include $(DEVKITPRO)/devkitA64/base_rules +export AMSLIBSDIR := $(TOPDIR)/../libraries + AMSBRANCH := $(shell git symbolic-ref --short HEAD) AMSHASH = $(shell git rev-parse --short=16 HEAD) AMSREV := $(AMSBRANCH)-$(shell git rev-parse --short HEAD) @@ -49,17 +51,16 @@ endif #--------------------------------------------------------------------------------- TARGET := $(notdir $(CURDIR)) BUILD := build -SOURCES := src src/platform src/gdb $(PLATFORM_SOURCES) +SOURCES := src src/libc src/platform src/gdb $(PLATFORM_SOURCES) DATA := data -INCLUDES := include ../common/include +INCLUDES := #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- # Note: -ffixed-x18 and -mgeneral-regs-only are very important and must be enabled ARCH := -march=armv8-a -mtune=cortex-a57 -mgeneral-regs-only -ffixed-x18 -Wno-psabi -DEFINES := -D__CCPLEX__ -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\"\ - -DATMOSPHERE_RELEASE_VERSION_HASH="0x$(AMSHASH)" $(PLATFORM_DEFINES) +DEFINES := $(PLATFORM_DEFINES) CFLAGS := \ -g \ -fmacro-prefix-map=$(TOPDIR)/src/= \ @@ -68,20 +69,36 @@ CFLAGS := \ -fdata-sections \ -fomit-frame-pointer \ -fno-asynchronous-unwind-tables \ - -fstrict-volatile-bitfields \ -fno-unwind-tables \ - -std=gnu11 \ + -fno-stack-protector \ + -fstrict-volatile-bitfields \ -Wall \ -Werror \ -Wno-main \ $(ARCH) $(DEFINES) -CFLAGS += $(INCLUDE) +export CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \ + -Wl,--wrap,__cxa_throw \ + -Wl,--wrap,__cxa_rethrow \ + -Wl,--wrap,__cxa_allocate_exception \ + -Wl,--wrap,__cxa_free_exception \ + -Wl,--wrap,__cxa_begin_catch \ + -Wl,--wrap,__cxa_end_catch \ + -Wl,--wrap,__cxa_call_unexpected \ + -Wl,--wrap,__cxa_call_terminate \ + -Wl,--wrap,__gxx_personality_v0 \ + -Wl,--wrap,_Unwind_Resume \ + -Wl,--wrap,_Unwind_Resume \ + -Wl,--wrap,_ZSt19__throw_logic_errorPKc \ + -Wl,--wrap,_ZSt20__throw_length_errorPKc \ + -Wl,--wrap,_ZNSt11logic_errorC2EPKc -CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11 +CFLAGS += $(INCLUDE) +CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++2a +CFLAGS += -std=gnu11 ASFLAGS := -g $(ARCH) $(DEFINES) -LDFLAGS = -specs=$(TOPDIR)/linker.specs -nostartfiles -nostdlib -g $(ARCH) -Wl,-Map,$(notdir $*.map) +LDFLAGS = -specs=$(TOPDIR)/linker.specs -nostartfiles -nostdlib -g $(ARCH) $(CXXWRAPS) -Wl,-Map,$(notdir $*.map) LIBS := -lgcc @@ -89,7 +106,7 @@ LIBS := -lgcc # list of directories containing libraries, this must be the top level containing # include and lib #--------------------------------------------------------------------------------- -LIBDIRS := +LIBDIRS := $(AMSLIBSDIR)/libvapours #--------------------------------------------------------------------------------- diff --git a/thermosphere/src/abort.cpp b/thermosphere/src/abort.cpp new file mode 100644 index 000000000..10ab54c12 --- /dev/null +++ b/thermosphere/src/abort.cpp @@ -0,0 +1,54 @@ +/* + * 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 "defines.hpp" + +extern "C" { + + /* Redefine abort to trigger these handlers. */ + void abort(); + + /* Redefine C++ exception handlers. Requires wrap linker flag. */ + #define WRAP_ABORT_FUNC(func) void NORETURN __wrap_##func(void) { abort(); __builtin_unreachable(); } + WRAP_ABORT_FUNC(__cxa_pure_virtual) + WRAP_ABORT_FUNC(__cxa_throw) + WRAP_ABORT_FUNC(__cxa_rethrow) + WRAP_ABORT_FUNC(__cxa_allocate_exception) + WRAP_ABORT_FUNC(__cxa_free_exception) + WRAP_ABORT_FUNC(__cxa_begin_catch) + WRAP_ABORT_FUNC(__cxa_end_catch) + WRAP_ABORT_FUNC(__cxa_call_unexpected) + WRAP_ABORT_FUNC(__cxa_call_terminate) + WRAP_ABORT_FUNC(__gxx_personality_v0) + WRAP_ABORT_FUNC(_ZSt19__throw_logic_errorPKc) + WRAP_ABORT_FUNC(_ZSt20__throw_length_errorPKc) + WRAP_ABORT_FUNC(_ZNSt11logic_errorC2EPKc) + + /* TODO: We may wish to consider intentionally not defining an _Unwind_Resume wrapper. */ + /* This would mean that a failure to wrap all exception functions is a linker error. */ + WRAP_ABORT_FUNC(_Unwind_Resume) + #undef WRAP_ABORT_FUNC + +} + +/* Custom abort handler, so that std::abort will trigger these. */ +void abort() +{ +#ifndef PLATFORM_QEMU + __builtin_trap(); +#endif + for (;;); +} \ No newline at end of file diff --git a/thermosphere/src/utils.c b/thermosphere/src/defines.hpp similarity index 65% rename from thermosphere/src/utils.c rename to thermosphere/src/defines.hpp index 823e1b6b9..7cee9f985 100644 --- a/thermosphere/src/utils.c +++ b/thermosphere/src/defines.hpp @@ -1,29 +1,27 @@ -/* - * Copyright (c) 2018-2019 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 "utils.h" -#include "spinlock.h" -#include "caches.h" - -__attribute__((noinline)) bool overlaps(u64 as, u64 ae, u64 bs, u64 be) -{ - if(as <= bs && bs < ae) - return true; - if(bs <= as && as < be) - return true; - return false; -} +/* + * 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 + +#include +#include +#include +#include +#include +#include + +using std::size_t; \ No newline at end of file diff --git a/thermosphere/src/gdb/context.c b/thermosphere/src/gdb/context.c index ecb0e66a9..e09b3b515 100644 --- a/thermosphere/src/gdb/context.c +++ b/thermosphere/src/gdb/context.c @@ -24,7 +24,7 @@ #include -#include "context.h" +//#include "context.h" #include "net.h" diff --git a/thermosphere/src/gdb/context.h b/thermosphere/src/gdb/context.h deleted file mode 100644 index c3f4e3c6a..000000000 --- a/thermosphere/src/gdb/context.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2019 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 . - */ - -// Lots of code from: -/* -* This file is part of Luma3DS. -* Copyright (C) 2016-2019 Aurora Wright, TuxSH -* -* SPDX-License-Identifier: (MIT OR GPL-2.0-or-later) -*/ - -#pragma once - -#include "defines.h" -#include "../transport_interface.h" - -typedef struct PackedGdbHioRequest -{ - char magic[4]; // "GDB\x00" - u32 version; - - // Request - char functionName[16+1]; - char paramFormat[8+1]; - - u64 parameters[8]; - size_t stringLengths[8]; - - // Return - s64 retval; - int gdbErrno; - bool ctrlC; -} PackedGdbHioRequest; - -enum { - GDB_FLAG_NOACK = BIT(0), - GDB_FLAG_CONTINUING = BIT(1), - GDB_FLAG_TERMINATE = BIT(2), - GDB_FLAG_ATTACHED_AT_START = BIT(3), - GDB_FLAG_NONSTOP = BIT(4), -}; - -typedef enum GDBState -{ - GDB_STATE_DISCONNECTED, - GDB_STATE_CONNECTED, - GDB_STATE_ATTACHED, - GDB_STATE_DETACHING, -} GDBState; - -struct DebugEventInfo; - -typedef struct GDBContext { - // No need for a lock, it's in the transport interface layer... - - TransportInterface *transportInterface; - u32 flags; - GDBState state; - bool noAckSent; - - u32 attachedCoreList; - - int selectedThreadId; - int selectedThreadIdForContinuing; - - u32 sentDebugEventCoreList; - u32 acknowledgedDebugEventCoreList; - - bool sendOwnDebugEventDisallowed; - - bool catchThreadEvents; - bool processEnded, processExited; - - const struct DebugEventInfo *lastDebugEvent; - - uintptr_t currentHioRequestTargetAddr; - PackedGdbHioRequest currentHioRequest; - - size_t targetXmlLen; - - char *commandData, *commandEnd; - size_t lastSentPacketSize; - char *buffer; - char *workBuffer; -} GDBContext; - -typedef int (*GDBCommandHandler)(GDBContext *ctx); - -void GDB_InitializeContext(GDBContext *ctx, TransportInterfaceType ifaceType, u32 ifaceId, u32 ifaceFlags); - -void GDB_AttachToContext(GDBContext *ctx); -void GDB_DetachFromContext(GDBContext *ctx); - -void GDB_AcquireContext(GDBContext *ctx); -void GDB_ReleaseContext(GDBContext *ctx); -void GDB_MigrateRxIrq(GDBContext *ctx, u32 coreId); - -GDB_DECLARE_HANDLER(Unsupported); -GDB_DECLARE_HANDLER(EnableExtendedMode); - -static inline bool GDB_IsAttached(GDBContext *ctx) -{ - return ctx->state == GDB_STATE_ATTACHED; -} - -static inline bool GDB_IsNonStop(GDBContext *ctx) -{ - return (ctx->flags & GDB_FLAG_NONSTOP) != 0; -} diff --git a/thermosphere/src/gdb/debug.h b/thermosphere/src/gdb/debug.h index 668278029..b145b3dd3 100644 --- a/thermosphere/src/gdb/debug.h +++ b/thermosphere/src/gdb/debug.h @@ -7,7 +7,7 @@ #pragma once -#include "context.h" +#include "gdb_context.hpp" #include "../core_ctx.h" #include "../debug_manager.h" @@ -15,14 +15,3 @@ int GDB_SendStopReply(GDBContext *ctx, const DebugEventInfo *info, bool asNotifi int GDB_TrySignalDebugEvent(GDBContext *ctx, DebugEventInfo *info); void GDB_BreakAllCores(GDBContext *ctx); - -GDB_DECLARE_VERBOSE_HANDLER(Stopped); - -GDB_DECLARE_HANDLER(Detach); -GDB_DECLARE_HANDLER(Kill); -GDB_DECLARE_VERBOSE_HANDLER(CtrlC); -GDB_DECLARE_HANDLER(ContinueOrStepDeprecated); -GDB_DECLARE_VERBOSE_HANDLER(Continue); -GDB_DECLARE_HANDLER(GetStopReason); - -//void GDB_BreakProcessAndSinkDebugEvents(GDBContext *ctx, DebugFlags flags); diff --git a/thermosphere/src/gdb/gdb_context.hpp b/thermosphere/src/gdb/gdb_context.hpp new file mode 100644 index 000000000..e8b18421a --- /dev/null +++ b/thermosphere/src/gdb/gdb_context.hpp @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2019 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 . + */ + +// Lots of code from: +/* +* This file is part of Luma3DS. +* Copyright (C) 2016-2019 Aurora Wright, TuxSH +* +* SPDX-License-Identifier: (MIT OR GPL-2.0-or-later) +*/ + +#pragma once + +#include "gdb_defines_internal.hpp" +#include "../transport_interface.h" + +namespace ams::hyp::gdb { + + struct PackedGdbHioRequest { + // TODO revamp + char magic[4]; // "GDB\x00" + u32 version; + + // Request + char functionName[16+1]; + char paramFormat[8+1]; + + u64 parameters[8]; + size_t stringLengths[8]; + + // Return + s64 retval; + int gdbErrno; + bool ctrlC; + }; + + typedef enum GDBState + { + STATE_DISCONNECTED, + STATE_CONNECTED, + STATE_ATTACHED, + STATE_DETACHING, + } GDBState; + + struct DebugEventInfo; + + class Context final { + NON_COPYABLE(Context); + NON_MOVEABLE(Context); + + private: + enum class State { + Disconnected = 0, + Connected, + Attached, + Detaching + }; + + private: + // No need for a lock, it's in the transport interface layer... + TransportInterface *m_transportInterface = nullptr; + State m_state = State::Disconnected; + bool m_noAckSent = false; + bool m_noAck = false; + bool m_nonStop = false; + + u32 m_attachedCoreList = 0; + + int m_selectedThreadId = 0; + int m_selectedThreadIdForContinuing = 0; + + u32 m_sentDebugEventCoreList = 0; + u32 m_acknowledgedDebugEventCoreList = 0; + + bool m_sendOwnDebugEventDisallowed = 0; + + bool m_catchThreadEvents = false; + bool m_processEnded = false; + bool m_processExited = false; + + const struct DebugEventInfo *m_lastDebugEvent = nullptr; + uintptr_t m_currentHioRequestTargetAddr = 0ul; + PackedGdbHioRequest m_currentHioRequest{}; + + size_t m_targetXmlLen = 0; + + char *m_commandData = nullptr; + char *m_commandEnd = nullptr; + size_t m_lastSentPacketSize = 0ul; + char *m_buffer = nullptr; + char *m_workBuffer = nullptr; + + private: + void MigrateRxIrq(u32 coreId) const; + + DECLARE_HANDLER(Unsupported); + + // Debug + DECLARE_VERBOSE_HANDLER(Stopped); + DECLARE_HANDLER(Detach); + DECLARE_HANDLER(Kill); + DECLARE_VERBOSE_HANDLER(CtrlC); + DECLARE_HANDLER(ContinueOrStepDeprecated); + DECLARE_VERBOSE_HANDLER(Continue); + DECLARE_HANDLER(GetStopReason); + + public: + void Initialize(TransportInterfaceType ifaceType, u32 ifaceId, u32 ifaceFlags); + void Attach(); + void Detach(); + + void Acquire(); + void Release(); + + constexpr bool IsAttached() const + { + return m_state == State::Attached; + } + } +} \ No newline at end of file diff --git a/thermosphere/src/gdb/defines.h b/thermosphere/src/gdb/gdb_defines_internal.hpp similarity index 66% rename from thermosphere/src/gdb/defines.h rename to thermosphere/src/gdb/gdb_defines_internal.hpp index 5b0ea4a14..42e90c9cd 100644 --- a/thermosphere/src/gdb/defines.h +++ b/thermosphere/src/gdb/gdb_defines_internal.hpp @@ -24,7 +24,7 @@ #pragma once -#include "../utils.h" +#include "../defines.hpp" // 512+24 is the ideal size as IDA will try to read exactly 0x100 bytes at a time. // IDA seems to want additional bytes as well. @@ -33,10 +33,14 @@ #define GDB_BUF_LEN 0x800 #define GDB_WORK_BUF_LEN 0x1000 -#define GDB_HANDLER(name) GDB_Handle##name -#define GDB_QUERY_HANDLER(name) GDB_HANDLER(Query##name) -#define GDB_VERBOSE_HANDLER(name) GDB_HANDLER(Verbose##name) +#define HANDLER(name) Handle##name +#define QUERY_HANDLER(name) HANDLER(Query##name) +#define VERBOSE_HANDLER(name) HANDLER(Verbose##name) -#define GDB_DECLARE_HANDLER(name) int GDB_HANDLER(name)(GDBContext *ctx) -#define GDB_DECLARE_QUERY_HANDLER(name) GDB_DECLARE_HANDLER(Query##name) -#define GDB_DECLARE_VERBOSE_HANDLER(name) GDB_DECLARE_HANDLER(Verbose##name) +#define DECLARE_HANDLER(name) int HANDLER(name)() +#define DECLARE_QUERY_HANDLER(name) DECLARE_HANDLER(Query##name) +#define DECLARE_VERBOSE_HANDLER(name) DECLARE_HANDLER(Verbose##name) + +#define DEFINE_HANDLER(name) int Context::HANDLER(name)() +#define DEFINE_QUERY_HANDLER(name) DEFINE_HANDLER(Query##name) +#define DECLARE_VERBOSE_HANDLER(name) DEFINE_HANDLER(Verbose##name) \ No newline at end of file diff --git a/thermosphere/src/gdb/mem.h b/thermosphere/src/gdb/mem.h index b81f8b648..264f73f5f 100644 --- a/thermosphere/src/gdb/mem.h +++ b/thermosphere/src/gdb/mem.h @@ -12,8 +12,3 @@ int GDB_SendMemory(GDBContext *ctx, const char *prefix, size_t prefixLen, uintptr_t addr, size_t len); int GDB_WriteMemory(GDBContext *ctx, const void *buf, uintptr_t addr, size_t len); u32 GDB_SearchMemory(bool *found, GDBContext *ctx, size_t addr, size_t len, const void *pattern, size_t patternLen); - -GDB_DECLARE_HANDLER(ReadMemory); -GDB_DECLARE_HANDLER(WriteMemory); -GDB_DECLARE_HANDLER(WriteMemoryRaw); -GDB_DECLARE_QUERY_HANDLER(SearchMemory); diff --git a/thermosphere/src/fmt.c b/thermosphere/src/libc/fmt.c similarity index 81% rename from thermosphere/src/fmt.c rename to thermosphere/src/libc/fmt.c index f35c676b7..f352d5cb5 100644 --- a/thermosphere/src/fmt.c +++ b/thermosphere/src/libc/fmt.c @@ -46,9 +46,14 @@ This code is based on a file that contains the following: //TuxSH's changes: add support for 64-bit numbers, remove floating-point code +#ifdef __cplusplus +extern "C" { +#endif + #include #include -#include "types.h" +#include +#include #define ZEROPAD (1<<0) //Pad with zero #define SIGN (1<<1) //Unsigned/signed long @@ -60,16 +65,16 @@ This code is based on a file that contains the following: #define IS_DIGIT(c) ((c) >= '0' && (c) <= '9') -static s32 skipAtoi(const char **s) +static int skipAtoi(const char **s) { - s32 i = 0; + int i = 0; while(IS_DIGIT(**s)) i = i * 10 + *((*s)++) - '0'; return i; } -static char *processNumber(char *str, s64 num, bool isHex, s32 size, s32 precision, u32 type) +static char *processNumber(char *str, long long num, bool isHex, int size, int precision, unsigned int type) { char sign = 0; @@ -96,7 +101,7 @@ static char *processNumber(char *str, s64 num, bool isHex, s32 size, s32 precisi static const char *lowerDigits = "0123456789abcdef", *upperDigits = "0123456789ABCDEF"; - s32 i = 0; + int i = 0; char tmp[20]; const char *dig = (type & UPPERCASE) ? upperDigits : lowerDigits; @@ -109,9 +114,9 @@ static char *processNumber(char *str, s64 num, bool isHex, s32 size, s32 precisi { while(num != 0) { - u64 base = isHex ? 16ULL : 10ULL; - tmp[i++] = dig[(u64)num % base]; - num = (s64)((u64)num / base); + unsigned long long int base = isHex ? 16ULL : 10ULL; + tmp[i++] = dig[(unsigned long long int)num % base]; + num = (long long)((unsigned long long int)num / base); } } @@ -149,7 +154,7 @@ int vsprintf(char *buf, const char *fmt, va_list args) } //Process flags - u32 flags = 0; //Flags to number() + unsigned int flags = 0; //Flags to number() bool loop = true; while(loop) @@ -166,13 +171,13 @@ int vsprintf(char *buf, const char *fmt, va_list args) } //Get field width - s32 fieldWidth = -1; //Width of output field + int fieldWidth = -1; //Width of output field if(IS_DIGIT(*fmt)) fieldWidth = skipAtoi(&fmt); else if(*fmt == '*') { fmt++; - fieldWidth = va_arg(args, s32); + fieldWidth = va_arg(args, int); if(fieldWidth < 0) { @@ -182,7 +187,7 @@ int vsprintf(char *buf, const char *fmt, va_list args) } //Get the precision - s32 precision = -1; //Min. # of digits for integers; max number of chars for from string + int precision = -1; //Min. # of digits for integers; max number of chars for from string if(*fmt == '.') { fmt++; @@ -191,14 +196,14 @@ int vsprintf(char *buf, const char *fmt, va_list args) else if(*fmt == '*') { fmt++; - precision = va_arg(args, s32); + precision = va_arg(args, int); } if(precision < 0) precision = 0; } //Get the conversion qualifier - u32 integerType = 0; + unsigned int integerType = 0; if(*fmt == 'l') { if(*++fmt == 'l') @@ -227,7 +232,7 @@ int vsprintf(char *buf, const char *fmt, va_list args) { case 'c': if(!(flags & LEFT)) while(--fieldWidth > 0) *str++ = ' '; - *str++ = (u8)va_arg(args, s32); + *str++ = (unsigned char)va_arg(args, int); while(--fieldWidth > 0) *str++ = ' '; continue; @@ -235,10 +240,10 @@ int vsprintf(char *buf, const char *fmt, va_list args) { char *s = va_arg(args, char *); if(!s) s = ""; - u32 len = (precision != -1) ? strnlen(s, precision) : strlen(s); - if(!(flags & LEFT)) while((s32)len < fieldWidth--) *str++ = ' '; - for(u32 i = 0; i < len; i++) *str++ = *s++; - while((s32)len < fieldWidth--) *str++ = ' '; + unsigned int len = (precision != -1) ? strnlen(s, precision) : strlen(s); + if(!(flags & LEFT)) while((int)len < fieldWidth--) *str++ = ' '; + for(unsigned int i = 0; i < len; i++) *str++ = *s++; + while((int)len < fieldWidth--) *str++ = ' '; continue; } @@ -248,7 +253,7 @@ int vsprintf(char *buf, const char *fmt, va_list args) fieldWidth = 8; flags |= ZEROPAD; } - str = processNumber(str, va_arg(args, u32), true, fieldWidth, precision, flags); + str = processNumber(str, va_arg(args, unsigned int), true, fieldWidth, precision, flags); continue; //Integer number formats - set up the flags and "break" @@ -274,23 +279,23 @@ int vsprintf(char *buf, const char *fmt, va_list args) continue; } - s64 num; + long long num; if(flags & SIGN) { - if(integerType == 1) num = va_arg(args, s64); - else num = va_arg(args, s32); + if(integerType == 1) num = va_arg(args, signed long long int); + else num = va_arg(args, signed int); - if(integerType == 2) num = (s16)num; - else if(integerType == 3) num = (s8)num; + if(integerType == 2) num = (signed short)num; + else if(integerType == 3) num = (signed char)num; } else { - if(integerType == 1) num = va_arg(args, u64); - else num = va_arg(args, u32); + if(integerType == 1) num = va_arg(args, unsigned long long int); + else num = va_arg(args, unsigned int); - if(integerType == 2) num = (u16)num; - else if(integerType == 3) num = (u8)num; + if(integerType == 2) num = (unsigned short)num; + else if(integerType == 3) num = (unsigned char)num; } str = processNumber(str, num, isHex, fieldWidth, precision, flags); @@ -308,3 +313,8 @@ int sprintf(char *buf, const char *fmt, ...) va_end(args); return res; } + + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/thermosphere/src/my_libc.c b/thermosphere/src/libc/my_libc.c similarity index 100% rename from thermosphere/src/my_libc.c rename to thermosphere/src/libc/my_libc.c diff --git a/thermosphere/src/utils.h b/thermosphere/src/utils.h index 11659425d..b8d0c56e8 100644 --- a/thermosphere/src/utils.h +++ b/thermosphere/src/utils.h @@ -1,19 +1,3 @@ -/* - * Copyright (c) 2018-2019 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 "types.h"