소스 검색

Kernel: Add KString::must_{..} factory methods

There are a bunch of places like drivers which for all intense and
purposes can't really fail allocation during boot, and if they do
fail we should crash immediately.

This change adds `KString::must_create_uninitialized(..)` as well as
`KString::must_create(..)` for use during early boot initialization of
the Kernel. They enforce that they are only used during early boot.
Brian Gianforcaro 4 년 전
부모
커밋
d838a02e74
3개의 변경된 파일27개의 추가작업 그리고 0개의 파일을 삭제
  1. 20 0
      Kernel/KString.cpp
  2. 2 0
      Kernel/KString.h
  3. 5 0
      Kernel/init.cpp

+ 20 - 0
Kernel/KString.cpp

@@ -6,6 +6,8 @@
 
 #include <Kernel/KString.h>
 
+extern bool g_in_early_boot;
+
 namespace Kernel {
 
 OwnPtr<KString> KString::try_create(StringView const& string)
@@ -21,6 +23,15 @@ OwnPtr<KString> KString::try_create(StringView const& string)
     return new_string;
 }
 
+NonnullOwnPtr<KString> KString::must_create(StringView const& string)
+{
+    // We can only enforce success during early boot.
+    VERIFY(g_in_early_boot);
+    auto kstring = KString::try_create(string);
+    VERIFY(kstring != nullptr);
+    return kstring.release_nonnull();
+}
+
 OwnPtr<KString> KString::try_create_uninitialized(size_t length, char*& characters)
 {
     size_t allocation_size = sizeof(KString) + (sizeof(char) * length) + sizeof(char);
@@ -32,6 +43,15 @@ OwnPtr<KString> KString::try_create_uninitialized(size_t length, char*& characte
     return adopt_own_if_nonnull(new_string);
 }
 
+NonnullOwnPtr<KString> KString::must_create_uninitialized(size_t length, char*& characters)
+{
+    // We can only enforce success during early boot.
+    VERIFY(g_in_early_boot);
+    auto kstring = KString::try_create_uninitialized(length, characters);
+    VERIFY(kstring != nullptr);
+    return kstring.release_nonnull();
+}
+
 OwnPtr<KString> KString::try_clone() const
 {
     return try_create(view());

+ 2 - 0
Kernel/KString.h

@@ -14,7 +14,9 @@ namespace Kernel {
 class KString {
 public:
     static OwnPtr<KString> try_create_uninitialized(size_t, char*&);
+    static NonnullOwnPtr<KString> must_create_uninitialized(size_t, char*&);
     static OwnPtr<KString> try_create(StringView const&);
+    static NonnullOwnPtr<KString> must_create(StringView const&);
 
     OwnPtr<KString> try_clone() const;
 

+ 5 - 0
Kernel/init.cpp

@@ -78,6 +78,7 @@ multiboot_module_entry_t multiboot_copy_boot_modules_array[16];
 size_t multiboot_copy_boot_modules_count;
 
 extern "C" const char kernel_cmdline[4096];
+bool g_in_early_boot;
 
 namespace Kernel {
 
@@ -111,6 +112,7 @@ extern "C" UNMAP_AFTER_INIT [[noreturn]] void init()
         asm volatile("cli;hlt");
     }
 
+    g_in_early_boot = true;
     setup_serial_debug();
 
     // We need to copy the command line before kmalloc is initialized,
@@ -271,6 +273,9 @@ void init_stage2(void*)
     // NOTE: Everything marked UNMAP_AFTER_INIT becomes inaccessible after this point.
     MM.unmap_memory_after_init();
 
+    // Switch out of early boot mode.
+    g_in_early_boot = false;
+
     int error;
 
     // FIXME: It would be nicer to set the mode from userspace.