From 2367a9e4c76bf6a3e081fc9e7381d24bd5489866 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Sun, 29 Nov 2020 23:02:19 +0500 Subject: [PATCH] Add function "KernAux_Multiboot2_boot_cmd_line" --- .gitignore | 1 + Makefile.am | 6 ++ include/kernaux/multiboot2.h | 9 ++ src/multiboot2/helpers.c | 27 ++++++ src/multiboot2/print.c | 4 - tests/test_multiboot2_helpers.c | 142 ++++++++++++++++++++++++++++++++ 6 files changed, 185 insertions(+), 4 deletions(-) create mode 100644 src/multiboot2/helpers.c create mode 100644 tests/test_multiboot2_helpers.c diff --git a/.gitignore b/.gitignore index dec215c..0ab74b3 100644 --- a/.gitignore +++ b/.gitignore @@ -26,5 +26,6 @@ /tests/multiboot2_print1 /tests/multiboot2_print2 +/tests/test_multiboot2_helpers /tests/test_multiboot2_print /tests/test_multiboot2_validation diff --git a/Makefile.am b/Makefile.am index a78ee43..4d52593 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,6 +5,7 @@ AM_CFLAGS = -std=c99 -Wall -Wextra -I$(top_srcdir)/include lib_LIBRARIES = libkernaux.a TESTS = \ + tests/test_multiboot2_helpers \ tests/test_multiboot2_print \ tests/test_multiboot2_validation @@ -15,6 +16,7 @@ noinst_PROGRAMS = \ libkernaux_a_SOURCES = \ src/arch/i386.S \ + src/multiboot2/helpers.c \ src/multiboot2/is_valid.c \ src/multiboot2/print.c \ src/pfa.c @@ -27,6 +29,10 @@ tests_multiboot2_print2_SOURCES = \ $(libkernaux_a_SOURCES) \ tests/multiboot2_print2.c +tests_test_multiboot2_helpers_SOURCES = \ + $(libkernaux_a_SOURCES) \ + tests/test_multiboot2_helpers.c + tests_test_multiboot2_print_SOURCES = \ $(libkernaux_a_SOURCES) \ tests/test_multiboot2_print.c diff --git a/include/kernaux/multiboot2.h b/include/kernaux/multiboot2.h index 896de41..929a636 100644 --- a/include/kernaux/multiboot2.h +++ b/include/kernaux/multiboot2.h @@ -304,6 +304,15 @@ struct KernAux_Multiboot2_Tag_MemoryMap_EntryBase { } __attribute__((packed)); +/******************** + * Helper functions * + ********************/ + +const char *KernAux_Multiboot2_boot_cmd_line( + const struct KernAux_Multiboot2 *multiboot2 +) +__attribute__((nonnull)); + /******************* * Print functions * *******************/ diff --git a/src/multiboot2/helpers.c b/src/multiboot2/helpers.c new file mode 100644 index 0000000..e02beae --- /dev/null +++ b/src/multiboot2/helpers.c @@ -0,0 +1,27 @@ +#include + +const char *KernAux_Multiboot2_boot_cmd_line( + const struct KernAux_Multiboot2 *const multiboot2 +) { + const struct KernAux_Multiboot2_TagBase *tag_base = + (struct KernAux_Multiboot2_TagBase*)multiboot2->data; + + while ((void*)tag_base < (void*)multiboot2 + multiboot2->total_size) { + if (!KernAux_Multiboot2_TagBase_is_valid(tag_base)) { + return 0; + } + + if (tag_base->type == KERNAUX_MULTIBOOT2_TAGTYPE_BOOT_CMD_LINE) { + const struct KernAux_Multiboot2_Tag_BootCmdLine *const tag = + (struct KernAux_Multiboot2_Tag_BootCmdLine*)tag_base; + + return tag->cmdline; + } + + tag_base = (struct KernAux_Multiboot2_TagBase*)( + (void*)tag_base + ((tag_base->size + 7) & ~7) + ); + } + + return 0; +} diff --git a/src/multiboot2/print.c b/src/multiboot2/print.c index 798bdc9..5ac1309 100644 --- a/src/multiboot2/print.c +++ b/src/multiboot2/print.c @@ -77,10 +77,6 @@ void KernAux_Multiboot2_print( print(" size: %u\n", multiboot2->total_size); print(" reserved1: %u\n", multiboot2->reserved1); - if (multiboot2->total_size <= 8) { - return; - } - const struct KernAux_Multiboot2_TagBase *tag_base = (struct KernAux_Multiboot2_TagBase*)multiboot2->data; diff --git a/tests/test_multiboot2_helpers.c b/tests/test_multiboot2_helpers.c new file mode 100644 index 0000000..af193fd --- /dev/null +++ b/tests/test_multiboot2_helpers.c @@ -0,0 +1,142 @@ +#include + +#include + +static const struct { + struct KernAux_Multiboot2 multiboot2; + struct KernAux_Multiboot2_Tag_None tag_none; +} multiboot2_without_boot_cmd_line = { + .multiboot2 = { + .total_size = sizeof(multiboot2_without_boot_cmd_line), + .reserved1 = 0, + }, + .tag_none = { + .base = { + .type = KERNAUX_MULTIBOOT2_TAGTYPE_NONE, + .size = sizeof(multiboot2_without_boot_cmd_line.tag_none), + }, + }, +}; + +static const struct { + struct KernAux_Multiboot2 multiboot2; + + struct { + struct KernAux_Multiboot2_Tag_BootCmdLine tag; + char cmdline[14]; + } tag_boot_cmd_line; + + unsigned char _align1[2]; + + struct KernAux_Multiboot2_Tag_None tag_none; +} multiboot2_with_some_boot_cmd_line = { + .multiboot2 = { + .total_size = sizeof(multiboot2_with_some_boot_cmd_line), + .reserved1 = 0, + }, + .tag_boot_cmd_line = { + .tag = { + .base = { + .type = KERNAUX_MULTIBOOT2_TAGTYPE_BOOT_CMD_LINE, + .size = sizeof( + multiboot2_with_some_boot_cmd_line.tag_boot_cmd_line + ), + }, + }, + .cmdline = "Hello, World!\0", + }, + .tag_none = { + .base = { + .type = KERNAUX_MULTIBOOT2_TAGTYPE_NONE, + .size = sizeof(multiboot2_with_some_boot_cmd_line.tag_none), + }, + }, +}; + +static const struct { + struct KernAux_Multiboot2 multiboot2; + + struct { + struct KernAux_Multiboot2_Tag_BootCmdLine tag; + char cmdline[14]; + } tag_boot_cmd_line1; + + unsigned char _align1[2]; + + struct { + struct KernAux_Multiboot2_Tag_BootCmdLine tag; + char cmdline[13]; + } tag_boot_cmd_line2; + + unsigned char _align2[3]; + + struct KernAux_Multiboot2_Tag_None tag_none; +} multiboot2_with_two_boot_cmd_lines = { + .multiboot2 = { + .total_size = sizeof(multiboot2_with_two_boot_cmd_lines), + .reserved1 = 0, + }, + .tag_boot_cmd_line1 = { + .tag = { + .base = { + .type = KERNAUX_MULTIBOOT2_TAGTYPE_BOOT_CMD_LINE, + .size = sizeof( + multiboot2_with_two_boot_cmd_lines.tag_boot_cmd_line1 + ), + }, + }, + .cmdline = "Hello, World!\0", + }, + .tag_boot_cmd_line2 = { + .tag = { + .base = { + .type = KERNAUX_MULTIBOOT2_TAGTYPE_BOOT_CMD_LINE, + .size = sizeof( + multiboot2_with_two_boot_cmd_lines.tag_boot_cmd_line2 + ), + }, + }, + .cmdline = "Hello again!\0", + }, + .tag_none = { + .base = { + .type = KERNAUX_MULTIBOOT2_TAGTYPE_NONE, + .size = sizeof(multiboot2_with_two_boot_cmd_lines.tag_none), + }, + }, +}; + +int main() +{ + assert(KernAux_Multiboot2_is_valid( + &multiboot2_without_boot_cmd_line.multiboot2 + )); + + assert(KernAux_Multiboot2_is_valid( + &multiboot2_with_some_boot_cmd_line.multiboot2 + )); + + assert(KernAux_Multiboot2_is_valid( + &multiboot2_with_two_boot_cmd_lines.multiboot2 + )); + + assert( + KernAux_Multiboot2_boot_cmd_line( + &multiboot2_without_boot_cmd_line.multiboot2 + ) == 0 + ); + + assert( + KernAux_Multiboot2_boot_cmd_line( + &multiboot2_with_some_boot_cmd_line.multiboot2 + ) == multiboot2_with_some_boot_cmd_line.tag_boot_cmd_line.cmdline + ); + + assert( + KernAux_Multiboot2_boot_cmd_line( + &multiboot2_with_two_boot_cmd_lines.multiboot2 + ) == multiboot2_with_two_boot_cmd_lines.tag_boot_cmd_line1.cmdline + ); + + return 0; +}