From aba45b9b6723930026658f39b02ae8f91ec60018 Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Sat, 4 Feb 2023 00:00:59 -0800 Subject: [PATCH] [boot] Go back to loading symbol table in boot The symbol table needs to be passed to the panic handler very early in the kernel, loading it in init is far less useful. Return it to the boot directory and remove it from the initrd. --- scripts/bonnibel/manifest.py | 49 ++------------------------------- scripts/bonnibel/project.py | 9 ++++-- src/boot/bootconfig.cpp | 5 ++-- src/boot/bootconfig.h | 2 ++ src/boot/loader.cpp | 6 ++-- src/boot/main.cpp | 14 ++++++++-- src/boot/status.cpp | 2 ++ src/libraries/elf/elf/file.h | 21 +++++++------- src/libraries/elf/elf/headers.h | 2 +- src/libraries/elf/file.cpp | 15 +++++----- src/user/srv.init/loader.cpp | 4 +-- 11 files changed, 50 insertions(+), 79 deletions(-) diff --git a/scripts/bonnibel/manifest.py b/scripts/bonnibel/manifest.py index 3cc44ad..647989d 100644 --- a/scripts/bonnibel/manifest.py +++ b/scripts/bonnibel/manifest.py @@ -39,6 +39,8 @@ class Manifest: self.flags = config.get("flags", tuple()) + self.symbols = "" + initrd = config.get("initrd", dict()) self.initrd = { "name": initrd.get("name", "initrd.dat"), @@ -110,52 +112,7 @@ class Manifest: write_ent(self.kernel) write_ent(self.init) write_path(self.initrd["name"]) + write_path(self.symbols) for p in self.panics: write_ent(p) - - def write_init_config(self, path, modules): - from os.path import join - import struct - - with open(path, 'wb') as outfile: - magic = "jsixinit".encode("utf-8") # magic string - version = 1 - reserved = 0 - - string_data = bytearray() - - outfile.write(struct.pack("<8s BBH HH", - magic, - version, reserved, len(self.services), - len(self.data), len(self.drivers))) - - offset_ptr = outfile.tell() - outfile.write(struct.pack("(data) != jsixboot) - error::raise(uefi::status::load_error, L"Bad header in jsix_boot.dat"); + error::raise(uefi::status::load_error, L"Bad header in boot config"); const uint8_t version = *util::read(data); if (version != 1) - error::raise(uefi::status::incompatible_version, L"Bad version in jsix_boot.dat"); + error::raise(uefi::status::incompatible_version, L"Bad version in boot config"); uint8_t num_panics = *util::read(data); m_flags = *util::read(data); @@ -43,6 +43,7 @@ bootconfig::bootconfig(util::buffer data, uefi::boot_services *bs) read_descriptor(m_kernel, data); read_descriptor(m_init, data); m_initrd = read_string(data); + m_symbols = read_string(data); m_panics.count = num_panics; m_panics.pointer = new descriptor [num_panics]; diff --git a/src/boot/bootconfig.h b/src/boot/bootconfig.h index cb1d52f..1220b8d 100644 --- a/src/boot/bootconfig.h +++ b/src/boot/bootconfig.h @@ -31,6 +31,7 @@ public: inline const descriptor & kernel() const { return m_kernel; } inline const descriptor & init() const { return m_init; } inline const wchar_t * initrd() const { return m_initrd; } + inline const wchar_t * symbols() const { return m_symbols; } inline const descriptors & panics() { return m_panics; } private: @@ -39,6 +40,7 @@ private: descriptor m_init; descriptors m_panics; wchar_t const *m_initrd; + wchar_t const *m_symbols; }; } // namespace boot diff --git a/src/boot/loader.cpp b/src/boot/loader.cpp index 7d0d3c9..735036e 100644 --- a/src/boot/loader.cpp +++ b/src/boot/loader.cpp @@ -72,7 +72,7 @@ load_program( util::const_buffer data = load_file(disk, desc.path); - elf::file program(data.pointer, data.count); + elf::file program {data}; if (!program.valid()) { auto *header = program.header(); console::print(L" progam size: %d\r\n", data.count); @@ -91,7 +91,7 @@ load_program( verify_kernel_header(program, data); size_t num_sections = 0; - for (auto &seg : program.programs()) { + for (auto &seg : program.segments()) { if (seg.type == elf::segment_type::load) ++num_sections; } @@ -99,7 +99,7 @@ load_program( bootproto::program_section *sections = new bootproto::program_section [num_sections]; size_t next_section = 0; - for (auto &seg : program.programs()) { + for (auto &seg : program.segments()) { if (seg.type != elf::segment_type::load) continue; diff --git a/src/boot/main.cpp b/src/boot/main.cpp index 029023b..cbdbe2d 100644 --- a/src/boot/main.cpp +++ b/src/boot/main.cpp @@ -72,8 +72,8 @@ load_resources(bootproto::args *args, video::screen *screen, uefi::handle image, status_line status {L"Loading programs"}; fs::file disk = fs::get_boot_volume(image, bs); - fs::file bc_data = disk.open(L"jsix\\boot.conf"); - bootconfig bc {bc_data.load(), bs}; + util::buffer bc_data = loader::load_file(disk, L"jsix\\boot.conf"); + bootconfig bc {bc_data, bs}; args->kernel = loader::load_program(disk, L"kernel", bc.kernel(), true); args->init = loader::load_program(disk, L"init server", bc.init()); @@ -85,6 +85,8 @@ load_resources(bootproto::args *args, video::screen *screen, uefi::handle image, namespace bits = util::bits; using bootproto::desc_flags; + bool has_panic = false; + if (screen) { video::make_module(screen); @@ -93,19 +95,25 @@ load_resources(bootproto::args *args, video::screen *screen, uefi::handle image, for (const descriptor &d : bc.panics()) { if (bits::has(d.flags, desc_flags::graphical)) { args->panic = loader::load_program(disk, L"panic handler", d); + has_panic = true; break; } } } - if (!args->panic) { + if (!has_panic) { for (const descriptor &d : bc.panics()) { if (!bits::has(d.flags, desc_flags::graphical)) { args->panic = loader::load_program(disk, L"panic handler", d); + has_panic = true; break; } } } + + const wchar_t *symbol_file = bc.symbols(); + if (has_panic && symbol_file && *symbol_file) + args->symbol_table = loader::load_file(disk, symbol_file).pointer; } memory::efi_mem_map diff --git a/src/boot/status.cpp b/src/boot/status.cpp index ed48fda..9e4005f 100644 --- a/src/boot/status.cpp +++ b/src/boot/status.cpp @@ -158,6 +158,8 @@ status_line::do_fail(const wchar_t *message, uefi::status status) void status_line::do_blank() { + m_level = level_ok; // Keep print_status_tag from happening in dtor + auto out = console::get().m_out; int row = out->mode->cursor_row; diff --git a/src/libraries/elf/elf/file.h b/src/libraries/elf/elf/file.h index 7b9edda..1b1c151 100644 --- a/src/libraries/elf/elf/file.h +++ b/src/libraries/elf/elf/file.h @@ -2,12 +2,13 @@ #include #include +#include #include namespace elf { struct file_header; -struct program_header; +struct segment_header; struct section_header; template @@ -37,9 +38,8 @@ class file { public: /// Constructor: Create an elf object out of ELF data in memory - /// \arg data The ELF data to read - /// \arg size Size of the ELF data, in bytes - file(const void *data, size_t size); + /// \arg data A const_buffer pointing at the ELF data + file(util::const_buffer data); /// Check the validity of the ELF data /// \returns true for valid ELF data @@ -51,25 +51,24 @@ public: /// Get the base address of the program in memory inline uintptr_t base() const { - return reinterpret_cast(m_data); + return reinterpret_cast(m_data.pointer); } - /// Get the ELF program headers - inline const subheaders & programs() const { return m_programs; } + /// Get the ELF segment headers + inline const subheaders & segments() const { return m_segments; } /// Get the ELF section headers inline const subheaders & sections() const { return m_sections; } inline const file_header * header() const { - return reinterpret_cast(m_data); + return reinterpret_cast(m_data.pointer); } private: - subheaders m_programs; + subheaders m_segments; subheaders m_sections; - const void *m_data; - size_t m_size; + util::const_buffer m_data; }; } diff --git a/src/libraries/elf/elf/headers.h b/src/libraries/elf/elf/headers.h index f5b5402..1afc292 100644 --- a/src/libraries/elf/elf/headers.h +++ b/src/libraries/elf/elf/headers.h @@ -63,7 +63,7 @@ enum class segment_flags : uint32_t }; is_bitfield(segment_flags); -struct program_header +struct segment_header { segment_type type; segment_flags flags; diff --git a/src/libraries/elf/file.cpp b/src/libraries/elf/file.cpp index 2ccb641..2bb0dd3 100644 --- a/src/libraries/elf/file.cpp +++ b/src/libraries/elf/file.cpp @@ -5,25 +5,24 @@ static const uint32_t expected_magic = 0x464c457f; // "\x7f" "ELF" namespace elf { -inline const file_header * fh(const void *data) { return reinterpret_cast(data); } +inline const file_header * fh(util::const_buffer data) { return reinterpret_cast(data.pointer); } template -const T *convert(const void *data, size_t offset) { - return reinterpret_cast(util::offset_pointer(data, offset)); +const T *convert(util::const_buffer data, size_t offset) { + return reinterpret_cast(util::offset_pointer(data.pointer, offset)); } -file::file(const void *data, size_t size) : - m_programs(convert(data, fh(data)->ph_offset), fh(data)->ph_entsize, fh(data)->ph_num), +file::file(util::const_buffer data) : + m_segments(convert(data, fh(data)->ph_offset), fh(data)->ph_entsize, fh(data)->ph_num), m_sections(convert(data, fh(data)->sh_offset), fh(data)->sh_entsize, fh(data)->sh_num), - m_data(data), - m_size(size) + m_data(data) { } bool file::valid() const { - if (m_size < sizeof(file_header)) + if (m_data.count < sizeof(file_header)) return false; const file_header *fheader = header(); diff --git a/src/user/srv.init/loader.cpp b/src/user/srv.init/loader.cpp index fbb2b3d..e2b7ef9 100644 --- a/src/user/srv.init/loader.cpp +++ b/src/user/srv.init/loader.cpp @@ -46,7 +46,7 @@ load_program( { uintptr_t base_address = reinterpret_cast(data.pointer); - elf::file progelf {data.pointer, data.count}; + elf::file progelf {data}; if (!progelf.valid()) { sprintf(err_msg, " ** error loading program '%s': ELF is invalid", name); @@ -72,7 +72,7 @@ load_program( return false; } - for (auto &seg : progelf.programs()) { + for (auto &seg : progelf.segments()) { if (seg.type != elf::segment_type::load) continue;