From b65f11d20572437df0732883852d01b2bc62bda8 Mon Sep 17 00:00:00 2001
From: TuxSH <1922548+TuxSH@users.noreply.github.com>
Date: Tue, 4 Feb 2020 18:50:32 +0000
Subject: [PATCH] wip
---
thermosphere/Makefile | 37 +++--
thermosphere/src/abort.cpp | 54 +++++++
thermosphere/src/{utils.c => defines.hpp} | 56 ++++----
thermosphere/src/gdb/context.c | 2 +-
thermosphere/src/gdb/context.h | 122 ----------------
thermosphere/src/gdb/debug.h | 13 +-
thermosphere/src/gdb/gdb_context.hpp | 133 ++++++++++++++++++
.../{defines.h => gdb_defines_internal.hpp} | 18 ++-
thermosphere/src/gdb/mem.h | 5 -
thermosphere/src/{ => libc}/fmt.c | 68 +++++----
thermosphere/src/{ => libc}/my_libc.c | 0
thermosphere/src/utils.h | 16 ---
12 files changed, 293 insertions(+), 231 deletions(-)
create mode 100644 thermosphere/src/abort.cpp
rename thermosphere/src/{utils.c => defines.hpp} (65%)
delete mode 100644 thermosphere/src/gdb/context.h
create mode 100644 thermosphere/src/gdb/gdb_context.hpp
rename thermosphere/src/gdb/{defines.h => gdb_defines_internal.hpp} (66%)
rename thermosphere/src/{ => libc}/fmt.c (81%)
rename thermosphere/src/{ => libc}/my_libc.c (100%)
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"