diff --git a/ELFLoader/ELFImage.cpp b/ELFLoader/ELFImage.cpp index ef812141843ce3..e7d75740664ba0 100644 --- a/ELFLoader/ELFImage.cpp +++ b/ELFLoader/ELFImage.cpp @@ -107,11 +107,13 @@ bool ELFImage::parse() } } +#ifdef SUPPORT_RELOCATIONS // Then create a name-to-index map. for (unsigned i = 0; i < section_count(); ++i) { auto& section = this->section(i); m_sections.set(section.name(), move(i)); } +#endif return true; } @@ -172,6 +174,7 @@ const ELFImage::ProgramHeader ELFImage::program_header(unsigned index) const return ProgramHeader(*this, index); } +#ifdef SUPPORT_RELOCATIONS const ELFImage::Relocation ELFImage::RelocationSection::relocation(unsigned index) const { ASSERT(index < relocation_count()); @@ -204,4 +207,5 @@ const ELFImage::Section ELFImage::lookupSection(const char* name) const return section((*it).value); return section(0); } +#endif diff --git a/ELFLoader/ELFImage.h b/ELFLoader/ELFImage.h index a38fb5c359832b..24bf890a3bafbf 100644 --- a/ELFLoader/ELFImage.h +++ b/ELFLoader/ELFImage.h @@ -88,7 +88,12 @@ class ELFImage { dword address() const { return m_section_header.sh_addr; } const char* raw_data() const { return m_image.raw_data(m_section_header.sh_offset); } bool is_undefined() const { return m_section_index == SHN_UNDEF; } +#ifdef SUPPORT_RELOCATIONS const RelocationSection relocations() const; +#endif + dword flags() const { return m_section_header.sh_flags; } + bool is_writable() const { return flags() & SHF_WRITE; } + bool is_executable() const { return flags() & PF_X; } protected: friend class RelocationSection; @@ -97,6 +102,7 @@ class ELFImage { unsigned m_section_index; }; +#ifdef SUPPORT_RELOCATIONS class RelocationSection : public Section { public: RelocationSection(const Section& section) @@ -127,6 +133,7 @@ class ELFImage { const ELFImage& m_image; const Elf32_Rel& m_rel; }; +#endif unsigned symbol_count() const; unsigned section_count() const; @@ -159,7 +166,9 @@ class ELFImage { const char* section_index_to_string(unsigned index); const byte* m_buffer { nullptr }; +#ifdef SUPPORT_RELOCATIONS HashMap m_sections; +#endif bool m_valid { false }; unsigned m_symbol_table_section_index { 0 }; unsigned m_string_table_section_index { 0 }; @@ -184,6 +193,7 @@ inline void ELFImage::for_each_section_of_type(unsigned type, F func) const } } +#ifdef SUPPORT_RELOCATIONS template inline void ELFImage::RelocationSection::for_each_relocation(F func) const { @@ -192,6 +202,7 @@ inline void ELFImage::RelocationSection::for_each_relocation(F func) const break; } } +#endif template inline void ELFImage::for_each_symbol(F func) const diff --git a/ELFLoader/ELFLoader.cpp b/ELFLoader/ELFLoader.cpp index b7b206a0668ca4..324e2dff4bdec2 100644 --- a/ELFLoader/ELFLoader.cpp +++ b/ELFLoader/ELFLoader.cpp @@ -2,6 +2,7 @@ #include //#define ELFLOADER_DEBUG +//#define SUPPORT_RELOCATIONS ELFLoader::ELFLoader(const byte* buffer) : m_image(buffer) @@ -22,9 +23,10 @@ bool ELFLoader::load() if (!layout()) return false; - export_symbols(); +#ifdef SUPPORT_RELOCATIONS if (!perform_relocations()) return false; +#endif return true; } @@ -49,7 +51,7 @@ bool ELFLoader::layout() } }); - m_image.for_each_section_of_type(SHT_PROGBITS, [this] (const ELFImage::Section& section) { + m_image.for_each_section_of_type(SHT_PROGBITS, [] (const ELFImage::Section& section) { #ifdef ELFLOADER_DEBUG kprintf("ELFLoader: Copying progbits section: %s\n", section.name()); #endif @@ -62,11 +64,15 @@ bool ELFLoader::layout() #endif return true; } - memcpy(ptr, section.raw_data(), section.size()); + // If this section isn't writable, it's already mmapped. + if (section.is_writable()) + memcpy(ptr, section.raw_data(), section.size()); +#ifdef SUPPORT_RELOCATIONS m_sections.set(section.name(), move(ptr)); +#endif return true; }); - m_image.for_each_section_of_type(SHT_NOBITS, [this, &failed] (const ELFImage::Section& section) { + m_image.for_each_section_of_type(SHT_NOBITS, [&failed] (const ELFImage::Section& section) { #ifdef ELFLOADER_DEBUG kprintf("ELFLoader: Copying nobits section: %s\n", section.name()); #endif @@ -79,19 +85,24 @@ bool ELFLoader::layout() return false; } memset(ptr, 0, section.size()); +#ifdef SUPPORT_RELOCATIONS m_sections.set(section.name(), move(ptr)); +#endif return true; }); return !failed; } +#ifdef SUPPORT_RELOCATIONS void* ELFLoader::lookup(const ELFImage::Symbol& symbol) { if (symbol.section().is_undefined()) return symbol_ptr(symbol.name()); return area_for_section(symbol.section()) + symbol.value(); } +#endif +#ifdef SUPPORT_RELOCATIONS char* ELFLoader::area_for_section(const ELFImage::Section& section) { return area_for_section_name(section.name()); @@ -104,7 +115,9 @@ char* ELFLoader::area_for_section_name(const char* name) ASSERT_NOT_REACHED(); return nullptr; } +#endif +#ifdef SUPPORT_RELOCATIONS bool ELFLoader::perform_relocations() { #ifdef ELFLOADER_DEBUG @@ -166,39 +179,27 @@ bool ELFLoader::perform_relocations() }); return !failed; } +#endif -void ELFLoader::export_symbols() +char* ELFLoader::symbol_ptr(const char* name) { + char* found_ptr = nullptr; m_image.for_each_symbol([&] (const ELFImage::Symbol symbol) { -#ifdef ELFLOADER_DEBUG - kprintf("symbol: %u, type=%u, name=%s, section=%u\n", symbol.index(), symbol.type(), symbol.name(), symbol.sectionIndex()); -#endif - if (symbol.type() == STT_FUNC) { - char* ptr; - if (m_image.is_executable()) - ptr = (char*)symbol.value(); - else if (m_image.is_relocatable()) - ptr = area_for_section(symbol.section()) + symbol.value(); - else - ASSERT_NOT_REACHED(); - add_symbol(symbol.name(), ptr, symbol.size()); - } - // FIXME: What about other symbol types? - return true; + if (symbol.type() != STT_FUNC) + return true; + if (strcmp(symbol.name(), name)) + return true; + if (m_image.is_executable()) + found_ptr = (char*)symbol.value(); +#ifdef SUPPORT_RELOCATIONS + else if (m_image.is_relocatable()) + found_ptr = area_for_section(symbol.section()) + symbol.value(); +#endif + else + ASSERT_NOT_REACHED(); + return false; }); -} - -char* ELFLoader::symbol_ptr(const char* name) -{ - if (auto it = m_symbols.find(name); it != m_symbols.end()) { - auto& symbol = (*it).value; -#ifdef EXECSPACE_DEBUG - kprintf("[ELFLoader] symbol_ptr(%s) dump:\n", name); - disassemble(symbol.ptr, symbol.size); -#endif - return symbol.ptr; - } - return nullptr; + return found_ptr; } bool ELFLoader::allocate_section(LinearAddress laddr, size_t size, size_t alignment, bool is_readable, bool is_writable) @@ -216,8 +217,3 @@ bool ELFLoader::map_section(LinearAddress laddr, size_t size, size_t alignment, ksprintf(namebuf, "elf-map-%s%s", is_readable ? "r" : "", is_writable ? "w" : ""); return map_section_hook(laddr, size, alignment, offset_in_image, is_readable, is_writable, namebuf); } - -void ELFLoader::add_symbol(String&& name, char* ptr, unsigned size) -{ - m_symbols.set(move(name), { ptr, size }); -} diff --git a/ELFLoader/ELFLoader.h b/ELFLoader/ELFLoader.h index 5e2749717618b5..b364ce7299cf8f 100644 --- a/ELFLoader/ELFLoader.h +++ b/ELFLoader/ELFLoader.h @@ -15,14 +15,12 @@ class ELFLoader { Function alloc_section_hook; Function map_section_hook; char* symbol_ptr(const char* name); - void add_symbol(String&& name, char* ptr, unsigned size); bool allocate_section(LinearAddress, size_t, size_t alignment, bool is_readable, bool is_writable); bool map_section(LinearAddress, size_t, size_t alignment, size_t offset_in_image, bool is_readable, bool is_writable); private: bool layout(); bool perform_relocations(); - void export_symbols(); void* lookup(const ELFImage::Symbol&); char* area_for_section(const ELFImage::Section&); char* area_for_section_name(const char*); @@ -40,7 +38,6 @@ class ELFLoader { }; ELFImage m_image; - HashMap m_symbols; HashMap m_sections; }; diff --git a/Kernel/i386.h b/Kernel/i386.h index 0eaae76ce013d1..b4c64b62470bcf 100644 --- a/Kernel/i386.h +++ b/Kernel/i386.h @@ -1,6 +1,7 @@ #pragma once #include "types.h" +#include "kprintf.h" #define PAGE_SIZE 4096 #define PAGE_MASK 0xfffff000 @@ -218,3 +219,35 @@ class CPUID { dword m_ecx { 0xffffffff }; dword m_edx { 0xffffffff }; }; + +inline void read_tsc(dword& lsw, dword& msw) +{ + asm volatile("rdtsc":"=d"(msw),"=a"(lsw)); +} + +struct Stopwatch { +public: + Stopwatch(const char* name) + : m_name(name) + { + read_tsc(m_start_lsw, m_start_msw); + } + + ~Stopwatch() + { + dword end_lsw; + dword end_msw; + read_tsc(end_lsw, end_msw); + if (m_start_msw != end_msw) { + dbgprintf("differing msw's\n"); + asm volatile("cli;hlt"); + } + dword diff = end_lsw - m_start_lsw; + dbgprintf("Stopwatch(%s): %u ticks\n", m_name, diff); + } + +private: + const char* m_name { nullptr }; + dword m_start_lsw { 0 }; + dword m_start_msw { 0 }; +};