9 次代碼提交 49d75449f0 ... 46c61c61ea

作者 SHA1 備註 提交日期
  coderain 46c61c61ea Fix a bug in free_page. 6 年之前
  coderain 95d13d26be Make sure the IOCTL buffers are optional. 6 年之前
  coderain 82ffccf3e4 Switch to the context of the kernel process in vm86_interrupt. 6 年之前
  coderain 59661c59c7 Fix a bug in wait_for_objects. 6 年之前
  coderain 52c5ee0487 Improve process/thread termination. 6 年之前
  coderain af25f21d70 Fix the security check for framebuffer mapping. 6 年之前
  coderain 568844d350 Fix bugs in the VESA driver. 6 年之前
  coderain 77d448de17 Improve logging. 6 年之前
  coderain 4309b04a86 Fix printf bugs. 6 年之前

+ 36 - 22
crt/src/printf.c

@@ -46,14 +46,16 @@ static int __crt_strputc(__crt_stream_or_string_t *str, char c)
     {
         return fputc_unlocked(c, str->stream) != EOF;
     }
-    else if (str->size > 1)
+    else
     {
-        *str->string++ = c;
-        str->size--;
+        if (str->size > 1)
+        {
+            *str->string++ = c;
+            str->size--;
+        }
+
         return 1;
     }
-
-    return 0;
 }
 
 static int __crt_strputs(__crt_stream_or_string_t *str, const char *s)
@@ -62,16 +64,28 @@ static int __crt_strputs(__crt_stream_or_string_t *str, const char *s)
     {
         return fputs_unlocked(s, str->stream) != EOF ? strlen(s) : 0;
     }
-    else if (str->size > 1)
+    else
     {
         int length = strlen(s);
-        strncpy(str->string, s, str->size - 1);
-        if (length > (str->size - 1)) length = str->size - 1;
-        str->string += length;
-        str->size -= length;
-    }
 
-    return 0;
+        if (str->size > 1)
+        {
+            strncpy(str->string, s, str->size - 1);
+
+            if (length < str->size)
+            {
+                str->string += length;
+                str->size -= length;
+            }
+            else
+            {
+                str->string += str->size - 1;
+                str->size = 0;
+            }
+        }
+
+        return length;
+    }
 }
 
 static inline int __crt_vstrprintf(__crt_stream_or_string_t *str, const char *format, va_list ap)
@@ -213,7 +227,7 @@ static inline int __crt_vstrprintf(__crt_stream_or_string_t *str, const char *fo
                 {
                     while (length < width)
                     {
-                        __crt_strputc(str, padding);
+                        ret += __crt_strputc(str, padding);
                         length++;
                     }
                 }
@@ -222,13 +236,13 @@ static inline int __crt_vstrprintf(__crt_stream_or_string_t *str, const char *fo
                 {
                     while (*data && precision > 0)
                     {
-                        __crt_strputc(str, *data++);
+                        ret += __crt_strputc(str, *data++);
                         precision--;
                     }
                 }
                 else
                 {
-                    __crt_strputs(str, data ? data : "(null)");
+                    ret += __crt_strputs(str, data ? data : "(null)");
                 }
                 break;
 
@@ -242,12 +256,12 @@ static inline int __crt_vstrprintf(__crt_stream_or_string_t *str, const char *fo
                 {
                     if (*data == '-')
                     {
-                        __crt_strputc(str, '-');
+                        ret += __crt_strputc(str, '-');
                         data++;
                     }
                     else
                     {
-                        __crt_strputc(str, (flags & __CRT_PRINTF_FLAG_PLUS) ? '+' : ' ');
+                        ret += __crt_strputc(str, (flags & __CRT_PRINTF_FLAG_PLUS) ? '+' : ' ');
                         length++;
                     }
                 }
@@ -256,13 +270,13 @@ static inline int __crt_vstrprintf(__crt_stream_or_string_t *str, const char *fo
                 {
                     while (length < width - precision)
                     {
-                        __crt_strputc(str, padding);
+                        ret += __crt_strputc(str, padding);
                         length++;
                     }
 
                     while (length < width)
                     {
-                        __crt_strputc(str, '0');
+                        ret += __crt_strputc(str, '0');
                         length++;
                     }
                 }
@@ -270,18 +284,18 @@ static inline int __crt_vstrprintf(__crt_stream_or_string_t *str, const char *fo
                 {
                     while (length < precision)
                     {
-                        __crt_strputc(str, '0');
+                        ret += __crt_strputc(str, '0');
                         length++;
                     }
                 }
 
-                __crt_strputs(str, data);
+                ret += __crt_strputs(str, data);
                 break;
             }
 
             while (length < width)
             {
-                __crt_strputc(str, padding);
+                ret += __crt_strputc(str, padding);
                 length++;
             }
         }

+ 10 - 6
drivers/vesa/src/main.c

@@ -102,25 +102,28 @@ dword_t vesa_init(list_entry_t *video_devices)
     if (ret != ERR_SUCCESS) goto cleanup;
 
     word_t *modes = (word_t*)((info.videomodes[1] << 4) + info.videomodes[0]);
-    ret = read_physical(modes, available_modes, sizeof(word_t) * MAX_NUM_MODES);
+    word_t *numbers = __builtin_alloca(sizeof(word_t) * MAX_NUM_MODES);
+    ret = read_physical(modes, numbers, sizeof(word_t) * MAX_NUM_MODES);
     if (ret != ERR_SUCCESS) goto cleanup;
 
     num_available_modes = 0;
 
-    for (i = 0; (available_mode_numbers[i] != 0xFFFF) && (i < MAX_NUM_MODES); i++)
+    for (i = 0; (numbers[i] != 0xFFFF) && (i < MAX_NUM_MODES); i++)
     {
         vbe_mode_info_t mode_info;
 
         regs.eax = 0x4F01;
-        regs.ecx = available_mode_numbers[i];
+        regs.ecx = numbers[i];
         regs.es = data_segment;
         regs.edi = 0x0000;
         vm86_interrupt(0x10, &regs);
-
         if (regs.eax != 0x4F) continue;
-        if (mode_info.mem_model_type != 0 && mode_info.mem_model_type != 4 && mode_info.mem_model_type != 6) continue;
 
         ret = read_physical((void*)(data_segment << 4), &mode_info, sizeof(vbe_mode_info_t));
+        if (mode_info.mem_model_type != 0 && mode_info.mem_model_type != 4 && mode_info.mem_model_type != 6) continue;
+
+        available_mode_numbers[num_available_modes] = numbers[i];
+        available_modes[num_available_modes] = mode_info;
         num_available_modes++;
     }
 
@@ -161,6 +164,7 @@ static dword_t vesa_control(video_device_t *device,
             if (ret != ERR_SUCCESS) return ret;
 
             device->current_mode = mode_info;
+            return ERR_SUCCESS;
         }
         else
         {
@@ -175,7 +179,7 @@ static dword_t vesa_control(video_device_t *device,
 
             list[0] = num_available_modes;
 
-            for (i = 0; i < num_available_modes && out_length >= (i * sizeof(dword_t)); i++)
+            for (i = 0; i < num_available_modes && out_length >= ((i + 2) * sizeof(dword_t)); i++)
             {
                 list[i + 1] = available_mode_numbers[i];
             }

+ 14 - 9
kernel/include/log.h

@@ -20,20 +20,22 @@
 #ifndef _LOG_H_
 #define _LOG_H_
 
-#include <common.h>
+#include <sdk/defs.h>
+#include <string.h>
 #include <stdarg.h>
 #include <stdio.h>
 
 #define MAX_LOG_MESSAGE_SIZE 256
 
 #ifdef DEBUG
-#define TRACE(x) log_write(LOG_DEBUG, x)
-#define FTRACE(x, args...) log_write(LOG_DEBUG, x, args)
+#define TRACE(x, ...) log_write(LOG_DEBUG, x, ##__VA_ARGS__)
 #else
-#define TRACE(x)
-#define FTRACE(x, ...)
+#define TRACE(x, ...)
 #endif
 
+/* For compatibility: */
+#define FTRACE TRACE
+
 typedef enum
 {
     LOG_DEBUG,
@@ -55,8 +57,11 @@ static inline void log_write(log_level_t level, const char *format, ...)
 
     va_list ap;
     va_start(ap, format);
-    char message[MAX_LOG_MESSAGE_SIZE];
-    vsnprintf(message, MAX_LOG_MESSAGE_SIZE, format, ap);
+
+    size_t length = vsnprintf(NULL, 0, format, ap);
+    char message[length + 1];
+    vsnprintf(message, length + 1, format, ap);
+
     va_end(ap);
 
     char *ptr = message;
@@ -66,7 +71,7 @@ static inline void log_write(log_level_t level, const char *format, ...)
         if (end) *end = '\0';
         else break;
 
-        char full_message[2 * MAX_LOG_MESSAGE_SIZE];
+        char full_message[strlen(log_buffer) + strlen(ptr) + 1];
         strcpy(full_message, log_buffer);
         strcat(full_message, ptr);
         append_log_entry(driver_name, level, full_message);
@@ -75,7 +80,7 @@ static inline void log_write(log_level_t level, const char *format, ...)
         ptr = end + 1;
     }
 
-    strcat(log_buffer, ptr);
+    strncat(log_buffer, ptr, sizeof(log_buffer) - strlen(log_buffer) - 1);
 }
 
 #endif

+ 1 - 0
kernel/include/process.h

@@ -79,6 +79,7 @@ void process_cleanup(object_t *proc);
 dword_t process_pre_wait(object_t *obj, void *parameter, wait_condition_t *condition);
 void destroy_process(process_t *process);
 process_t *switch_process(process_t *new_process);
+void terminate_process(process_t *proc, dword_t exit_code);
 void process_init(void);
 
 #endif

+ 25 - 13
kernel/src/device.c

@@ -426,25 +426,37 @@ sysret_t syscall_device_ioctl(handle_t device, dword_t control_code, const void
 
     if (get_previous_mode() == USER_MODE)
     {
-        if (!check_usermode(in_buffer, in_length)) return ERR_BADPTR;
-        if (!check_usermode(out_buffer, out_length)) return ERR_BADPTR;
+        if (in_buffer && !check_usermode(in_buffer, in_length)) return ERR_BADPTR;
+        if (out_buffer && !check_usermode(out_buffer, out_length)) return ERR_BADPTR;
 
-        safe_in_buffer = (byte_t*)malloc(in_length);
-        safe_out_buffer = (byte_t*)malloc(out_length);
-        if ((safe_in_buffer == NULL) || (safe_out_buffer == NULL))
+        if (in_buffer)
         {
-            ret = ERR_NOMEMORY;
-            goto cleanup;
+            if ((safe_in_buffer = (byte_t*)malloc(in_length)) == NULL)
+            {
+                ret = ERR_NOMEMORY;
+                goto cleanup;
+            }
+
+            EH_TRY
+            {
+                memcpy(safe_in_buffer, in_buffer, in_length);
+            }
+            EH_CATCH
+            {
+                ret = ERR_BADPTR;
+                EH_ESCAPE(goto cleanup);
+            }
+            EH_DONE;
         }
 
-        EH_TRY
+        if (out_buffer)
         {
-            memcpy(safe_in_buffer, in_buffer, in_length);
+            if ((safe_out_buffer = (byte_t*)malloc(out_length)) == NULL)
+            {
+                ret = ERR_NOMEMORY;
+                goto cleanup;
+            }
         }
-        EH_CATCH ret = ERR_BADPTR;
-        EH_DONE;
-
-        if (ret != ERR_SUCCESS) goto cleanup;
     }
     else
     {

+ 7 - 3
kernel/src/exception.c

@@ -59,9 +59,12 @@ static void raise_exception_internal(thread_t *thread, processor_mode_t mode, ex
         }
         else
         {
-            if (current) cpu_enable_interrupts();
-            terminate_thread_internal(thread, 1);
-            ASSERT(!current);
+
+            dword_t exit_code = 1; // TODO: Perhaps something more meaningful
+            process_t *proc = thread->owner_process;
+            reference(&proc->header);
+            terminate_process(proc, exit_code);
+            dereference(&proc->header);
         }
     }
     else
@@ -72,6 +75,7 @@ static void raise_exception_internal(thread_t *thread, processor_mode_t mode, ex
         if (thread->kernel_handler.eip)
         {
             thread->kernel_handler.eax = 1;
+            thread->in_kernel--;
             exception_return(thread->kernel_handler);
         }
         else

+ 3 - 7
kernel/src/interrupt.c

@@ -46,16 +46,12 @@ static void idt_main_handler(byte_t interrupt_num, registers_t regs)
     if (thread)
     {
         ASSERT(thread->in_kernel > 0);
+
         if (--thread->in_kernel == 0)
         {
             thread->last_context = NULL;
-
-            if (thread->terminated || (thread->frozen > 0))
-            {
-                cpu_enable_interrupts();
-                syscall_yield_quantum();
-            }
-
+            if (thread->terminating) thread->terminated = TRUE;
+            if (thread->terminated || thread->frozen > 0) syscall_yield_quantum();
             ASSERT(!thread->terminated && (thread->frozen <= 0));
         }
     }

+ 1 - 1
kernel/src/memory/memory.c

@@ -292,7 +292,7 @@ static inline dword_t free_page(void *virtual)
     unmap_page(virtual);
 
     page_t *page = get_page(phys);
-    if (page == NULL || page->ref_count == 0) free_physical_page(phys);
+    if (page != NULL && page->ref_count > 0) free_physical_page(phys);
 
     return ERR_SUCCESS;
 }

+ 1 - 1
kernel/src/object.c

@@ -650,7 +650,7 @@ static sysret_t wait_for_objects(const handle_t *handles, void * const *paramete
         goto cleanup;
     }
 
-    memset(condition, 0, sizeof(wait_condition_t) + (count + 1) * sizeof(wait_condition_t*));
+    memset(condition, 0, sizeof(wait_condition_t) + count * sizeof(wait_condition_t*));
     condition->type = condition_type;
 
     for (i = 0; i < count; i++)

+ 0 - 0
kernel/src/process.c


Some files were not shown because too many files changed in this diff