summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ELFLoader/ELFImage.cpp4
-rw-r--r--ELFLoader/ELFImage.h11
-rw-r--r--ELFLoader/ELFLoader.cpp72
-rw-r--r--ELFLoader/ELFLoader.h3
-rw-r--r--Kernel/i386.h33
5 files changed, 82 insertions, 41 deletions
diff --git a/ELFLoader/ELFImage.cpp b/ELFLoader/ELFImage.cpp
index ef81214184..e7d7574066 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 a38fb5c359..24bf890a3b 100644
--- a/ELFLoader/ELFImage.h
+++ b/ELFLoader/ELFImage.h
@@ -88,7 +88,12 @@ public:
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 @@ public:
unsigned m_section_index;
};
+#ifdef SUPPORT_RELOCATIONS
class RelocationSection : public Section {
public:
RelocationSection(const Section& section)
@@ -127,6 +133,7 @@ public:
const ELFImage& m_image;
const Elf32_Rel& m_rel;
};
+#endif
unsigned symbol_count() const;
unsigned section_count() const;
@@ -159,7 +166,9 @@ private:
const char* section_index_to_string(unsigned index);
const byte* m_buffer { nullptr };
+#ifdef SUPPORT_RELOCATIONS
HashMap<String, unsigned> 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<typename F>
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<typename F>
inline void ELFImage::for_each_symbol(F func) const
diff --git a/ELFLoader/ELFLoader.cpp b/ELFLoader/ELFLoader.cpp
index b7b206a066..324e2dff4b 100644
--- a/ELFLoader/ELFLoader.cpp
+++ b/ELFLoader/ELFLoader.cpp
@@ -2,6 +2,7 @@
#include <AK/kstdio.h>
//#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 5e27497176..b364ce7299 100644
--- a/ELFLoader/ELFLoader.h
+++ b/ELFLoader/ELFLoader.h
@@ -15,14 +15,12 @@ public:
Function<void*(LinearAddress, size_t, size_t, bool, bool, const String&)> alloc_section_hook;
Function<void*(LinearAddress, size_t, size_t, size_t, bool, bool, const String&)> 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 @@ private:
};
ELFImage m_image;
- HashMap<String, PtrAndSize> m_symbols;
HashMap<String, char*> m_sections;
};
diff --git a/Kernel/i386.h b/Kernel/i386.h
index 0eaae76ce0..b4c64b6247 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 @@ private:
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 };
+};