LibELF: Move ELF classes into namespace ELF

This is for consistency with other namespace changes that were made
a while back to the other libraries :)
This commit is contained in:
Andrew Kaster 2020-04-11 12:24:07 -06:00 committed by Andreas Kling
parent 6b0f47683c
commit 21b5909dc6
Notes: sideshowbarker 2024-07-19 07:42:08 +09:00
18 changed files with 203 additions and 169 deletions

View file

@ -27,7 +27,7 @@
#include "DisassemblyModel.h"
#include "Profile.h"
#include <AK/MappedFile.h>
#include <LibELF/ELFLoader.h>
#include <LibELF/Loader.h>
#include <LibGUI/Painter.h>
#include <LibX86/Disassembler.h>
#include <ctype.h>
@ -55,7 +55,7 @@ DisassemblyModel::DisassemblyModel(Profile& profile, ProfileNode& node)
, m_node(node)
{
m_file = make<MappedFile>(profile.executable_path());
auto elf_loader = make<ELFLoader>((const u8*)m_file->data(), m_file->size());
auto elf_loader = make<ELF::Loader>((const u8*)m_file->data(), m_file->size());
auto symbol = elf_loader->find_symbol(node.address());
ASSERT(symbol.has_value());

View file

@ -31,7 +31,7 @@
#include <AK/MappedFile.h>
#include <AK/QuickSort.h>
#include <LibCore/File.h>
#include <LibELF/ELFLoader.h>
#include <LibELF/Loader.h>
#include <stdio.h>
static void sort_profile_nodes(Vector<NonnullRefPtr<ProfileNode>>& nodes)
@ -185,12 +185,12 @@ OwnPtr<Profile> Profile::load_from_perfcore_file(const StringView& path)
return nullptr;
}
auto elf_loader = make<ELFLoader>(static_cast<const u8*>(elf_file.data()), elf_file.size());
auto elf_loader = make<ELF::Loader>(static_cast<const u8*>(elf_file.data()), elf_file.size());
MappedFile kernel_elf_file("/boot/kernel");
OwnPtr<ELFLoader> kernel_elf_loader;
OwnPtr<ELF::Loader> kernel_elf_loader;
if (kernel_elf_file.is_valid())
kernel_elf_loader = make<ELFLoader>(static_cast<const u8*>(kernel_elf_file.data()), kernel_elf_file.size());
kernel_elf_loader = make<ELF::Loader>(static_cast<const u8*>(kernel_elf_file.data()), kernel_elf_file.size());
auto events_value = object.get("events");
if (!events_value.is_array())

View file

@ -30,7 +30,7 @@
#include <Kernel/KSyms.h>
#include <Kernel/Process.h>
#include <Kernel/Scheduler.h>
#include <LibELF/ELFLoader.h>
#include <LibELF/Loader.h>
namespace Kernel {

View file

@ -9,8 +9,8 @@ OBJS = \
../AK/StringImpl.o \
../AK/StringUtils.o \
../AK/StringView.o \
../Libraries/LibELF/ELFImage.o \
../Libraries/LibELF/ELFLoader.o \
../Libraries/LibELF/Image.o \
../Libraries/LibELF/Loader.o \
../Libraries/LibBareMetal/Output/Console.o \
../Libraries/LibBareMetal/Output/kprintf.o \
../Libraries/LibBareMetal/StdLib.o \

View file

@ -77,7 +77,7 @@
#include <LibC/errno_numbers.h>
#include <LibC/limits.h>
#include <LibC/signal_numbers.h>
#include <LibELF/ELFLoader.h>
#include <LibELF/Loader.h>
//#define PROCESS_DEBUG
//#define DEBUG_POLL_SELECT
@ -856,7 +856,7 @@ int Process::do_exec(NonnullRefPtr<FileDescription> main_program_description, Ve
u32 entry_eip = 0;
MM.enter_process_paging_scope(*this);
OwnPtr<ELFLoader> loader;
OwnPtr<ELF::Loader> loader;
{
ArmedScopeGuard rollback_regions_guard([&]() {
ASSERT(Process::current == this);
@ -864,7 +864,7 @@ int Process::do_exec(NonnullRefPtr<FileDescription> main_program_description, Ve
m_regions = move(old_regions);
MM.enter_process_paging_scope(*this);
});
loader = make<ELFLoader>(region->vaddr().as_ptr(), loader_metadata.size);
loader = make<ELF::Loader>(region->vaddr().as_ptr(), loader_metadata.size);
// Load the correct executable -- either interp or main program.
// FIXME: Once we actually load both interp and main, we'll need to be more clever about this.
// In that case, both will be ET_DYN objects, so they'll both be completely relocatable.
@ -1084,14 +1084,14 @@ KResultOr<NonnullRefPtr<FileDescription>> Process::find_elf_interpreter_for_exec
return KResult(-ENOEXEC);
auto elf_header = (Elf32_Ehdr*)first_page;
if (!ELFImage::validate_elf_header(*elf_header, file_size)) {
if (!ELF::Image::validate_elf_header(*elf_header, file_size)) {
dbg() << "exec(" << path << "): File has invalid ELF header";
return KResult(-ENOEXEC);
}
// Not using KResultOr here because we'll want to do the same thing in userspace in the RTLD
String interpreter_path;
if (!ELFImage::validate_program_headers(*elf_header, file_size, (u8*)first_page, nread, interpreter_path)) {
if (!ELF::Image::validate_program_headers(*elf_header, file_size, (u8*)first_page, nread, interpreter_path)) {
dbg() << "exec(" << path << "): File has invalid ELF Program headers";
return KResult(-ENOEXEC);
}
@ -1124,14 +1124,14 @@ KResultOr<NonnullRefPtr<FileDescription>> Process::find_elf_interpreter_for_exec
return KResult(-ENOEXEC);
elf_header = (Elf32_Ehdr*)first_page;
if (!ELFImage::validate_elf_header(*elf_header, interp_metadata.size)) {
if (!ELF::Image::validate_elf_header(*elf_header, interp_metadata.size)) {
dbg() << "exec(" << path << "): Interpreter (" << interpreter_description->absolute_path() << ") has invalid ELF header";
return KResult(-ENOEXEC);
}
// Not using KResultOr here because we'll want to do the same thing in userspace in the RTLD
String interpreter_interpreter_path;
if (!ELFImage::validate_program_headers(*elf_header, interp_metadata.size, (u8*)first_page, nread, interpreter_interpreter_path)) {
if (!ELF::Image::validate_program_headers(*elf_header, interp_metadata.size, (u8*)first_page, nread, interpreter_interpreter_path)) {
dbg() << "exec(" << path << "): Interpreter (" << interpreter_description->absolute_path() << ") has invalid ELF Program headers";
return KResult(-ENOEXEC);
}
@ -4378,7 +4378,7 @@ int Process::sys$module_load(const char* user_path, size_t path_length)
memcpy(storage.data(), payload.data(), payload.size());
payload.clear();
auto elf_image = make<ELFImage>(storage.data(), storage.size());
auto elf_image = make<ELF::Image>(storage.data(), storage.size());
if (!elf_image->parse())
return -ENOEXEC;
@ -4386,7 +4386,7 @@ int Process::sys$module_load(const char* user_path, size_t path_length)
auto module = make<Module>();
elf_image->for_each_section_of_type(SHT_PROGBITS, [&](const ELFImage::Section& section) {
elf_image->for_each_section_of_type(SHT_PROGBITS, [&](const ELF::Image::Section& section) {
if (!section.size())
return IterationDecision::Continue;
auto section_storage = KBuffer::copy(section.raw_data(), section.size(), Region::Access::Read | Region::Access::Write | Region::Access::Execute);
@ -4397,12 +4397,12 @@ int Process::sys$module_load(const char* user_path, size_t path_length)
bool missing_symbols = false;
elf_image->for_each_section_of_type(SHT_PROGBITS, [&](const ELFImage::Section& section) {
elf_image->for_each_section_of_type(SHT_PROGBITS, [&](const ELF::Image::Section& section) {
if (!section.size())
return IterationDecision::Continue;
auto* section_storage = section_storage_by_name.get(section.name()).value_or(nullptr);
ASSERT(section_storage);
section.relocations().for_each_relocation([&](const ELFImage::Relocation& relocation) {
section.relocations().for_each_relocation([&](const ELF::Image::Relocation& relocation) {
auto& patch_ptr = *reinterpret_cast<ptrdiff_t*>(section_storage + relocation.offset());
switch (relocation.type()) {
case R_386_PC32: {
@ -4453,7 +4453,7 @@ int Process::sys$module_load(const char* user_path, size_t path_length)
return -EINVAL;
}
elf_image->for_each_symbol([&](const ELFImage::Symbol& symbol) {
elf_image->for_each_symbol([&](const ELF::Image::Symbol& symbol) {
dbg() << " - " << symbol.type() << " '" << symbol.name() << "' @ " << (void*)symbol.value() << ", size=" << symbol.size();
if (symbol.name() == "module_init") {
module->module_init = (ModuleInitPtr)(text_base + symbol.value());
@ -4845,7 +4845,7 @@ OwnPtr<Process::ELFBundle> Process::elf_bundle() const
bundle->region = MM.allocate_kernel_region_with_vmobject(const_cast<SharedInodeVMObject&>(vmobject), vmobject.size(), "ELF bundle", Region::Access::Read);
if (!bundle->region)
return nullptr;
bundle->elf_loader = make<ELFLoader>(bundle->region->vaddr().as_ptr(), bundle->region->size());
bundle->elf_loader = make<ELF::Loader>(bundle->region->vaddr().as_ptr(), bundle->region->size());
return bundle;
}

View file

@ -41,7 +41,9 @@
#include <Kernel/VM/RangeAllocator.h>
#include <LibC/signal_numbers.h>
class ELFLoader;
namespace ELF {
class Loader;
}
namespace Kernel {
@ -387,7 +389,7 @@ public:
struct ELFBundle {
OwnPtr<Region> region;
OwnPtr<ELFLoader> elf_loader;
OwnPtr<ELF::Loader> elf_loader;
};
OwnPtr<ELFBundle> elf_bundle() const;

View file

@ -31,7 +31,7 @@
#include <Kernel/KSyms.h>
#include <Kernel/Process.h>
#include <Kernel/Profiling.h>
#include <LibELF/ELFLoader.h>
#include <LibELF/Loader.h>
namespace Kernel {

View file

@ -38,7 +38,7 @@
#include <Kernel/VM/PageDirectory.h>
#include <Kernel/VM/ProcessPagingScope.h>
#include <LibC/signal_numbers.h>
#include <LibELF/ELFLoader.h>
#include <LibELF/Loader.h>
//#define SIGNAL_DEBUG
//#define THREAD_DEBUG

View file

@ -61,10 +61,10 @@ LIBC_OBJS = \
libcinit.o
ELF_OBJS = \
../LibELF/ELFDynamicObject.o \
../LibELF/ELFDynamicLoader.o \
../LibELF/ELFLoader.o \
../LibELF/ELFImage.o
../LibELF/DynamicObject.o \
../LibELF/DynamicLoader.o \
../LibELF/Loader.o \
../LibELF/Image.o
OBJS = $(AK_OBJS) $(LIBC_OBJS) $(ELF_OBJS)

View file

@ -38,12 +38,12 @@
#include <AK/ScopeGuard.h>
#include <AK/String.h>
#include <AK/StringBuilder.h>
#include <LibELF/ELFDynamicLoader.h>
#include <LibELF/DynamicLoader.h>
// NOTE: The string here should never include a trailing newline (according to POSIX)
String g_dlerror_msg;
HashMap<String, RefPtr<ELFDynamicLoader>> g_elf_objects;
HashMap<String, RefPtr<ELF::DynamicLoader>> g_elf_objects;
extern "C" {
@ -74,7 +74,7 @@ void* dlopen(const char* filename, int flags)
auto existing_elf_object = g_elf_objects.get(file_path.basename());
if (existing_elf_object.has_value()) {
return const_cast<ELFDynamicLoader*>(existing_elf_object.value());
return const_cast<ELF::DynamicLoader*>(existing_elf_object.value());
}
int fd = open(filename, O_RDONLY);
@ -93,7 +93,7 @@ void* dlopen(const char* filename, int flags)
return nullptr;
}
auto loader = ELFDynamicLoader::construct(filename, fd, file_stats.st_size);
auto loader = ELF::DynamicLoader::construct(filename, fd, file_stats.st_size);
if (!loader->is_valid()) {
g_dlerror_msg = String::format("%s is not a valid ELF dynamic shared object!", filename);
@ -109,14 +109,14 @@ void* dlopen(const char* filename, int flags)
g_dlerror_msg = "Successfully loaded ELF object.";
// we have one refcount already
return const_cast<ELFDynamicLoader*>(g_elf_objects.get(file_path.basename()).value());
return const_cast<ELF::DynamicLoader*>(g_elf_objects.get(file_path.basename()).value());
}
void* dlsym(void* handle, const char* symbol_name)
{
// FIXME: When called with a NULL handle we're supposed to search every dso in the process... that'll get expensive
ASSERT(handle);
auto* dso = reinterpret_cast<ELFDynamicLoader*>(handle);
auto* dso = reinterpret_cast<ELF::DynamicLoader*>(handle);
void* symbol = dso->symbol_for_name(symbol_name);
if (!symbol) {
g_dlerror_msg = "Symbol not found";

View file

@ -25,7 +25,7 @@
*/
#include <AK/StringBuilder.h>
#include <LibELF/ELFDynamicLoader.h>
#include <LibELF/DynamicLoader.h>
#include <assert.h>
#include <dlfcn.h>
@ -45,14 +45,16 @@
} while (0)
#endif
namespace ELF {
static bool s_always_bind_now = false;
NonnullRefPtr<ELFDynamicLoader> ELFDynamicLoader::construct(const char* filename, int fd, size_t size)
NonnullRefPtr<DynamicLoader> DynamicLoader::construct(const char* filename, int fd, size_t size)
{
return adopt(*new ELFDynamicLoader(filename, fd, size));
return adopt(*new DynamicLoader(filename, fd, size));
}
ELFDynamicLoader::ELFDynamicLoader(const char* filename, int fd, size_t size)
DynamicLoader::DynamicLoader(const char* filename, int fd, size_t size)
: m_filename(filename)
, m_file_size(size)
, m_image_fd(fd)
@ -65,13 +67,13 @@ ELFDynamicLoader::ELFDynamicLoader(const char* filename, int fd, size_t size)
}
}
ELFDynamicLoader::~ELFDynamicLoader()
DynamicLoader::~DynamicLoader()
{
if (MAP_FAILED != m_file_mapping)
munmap(m_file_mapping, m_file_size);
}
void* ELFDynamicLoader::symbol_for_name(const char* name)
void* DynamicLoader::symbol_for_name(const char* name)
{
auto symbol = m_dynamic_object->hash_section().lookup_symbol(name);
@ -81,9 +83,9 @@ void* ELFDynamicLoader::symbol_for_name(const char* name)
return m_dynamic_object->base_address().offset(symbol.value()).as_ptr();
}
bool ELFDynamicLoader::load_from_image(unsigned flags)
bool DynamicLoader::load_from_image(unsigned flags)
{
ELFImage elf_image((u8*)m_file_mapping, m_file_size);
Image elf_image((u8*)m_file_mapping, m_file_size);
m_valid = elf_image.is_valid() && elf_image.is_dynamic();
@ -101,12 +103,12 @@ bool ELFDynamicLoader::load_from_image(unsigned flags)
munmap(m_file_mapping, m_file_size);
m_file_mapping = MAP_FAILED;
m_dynamic_object = AK::make<ELFDynamicObject>(m_text_segment_load_address, m_dynamic_section_address);
m_dynamic_object = AK::make<DynamicObject>(m_text_segment_load_address, m_dynamic_section_address);
return load_stage_2(flags);
}
bool ELFDynamicLoader::load_stage_2(unsigned flags)
bool DynamicLoader::load_stage_2(unsigned flags)
{
ASSERT(flags & RTLD_GLOBAL);
ASSERT(flags & RTLD_LAZY);
@ -143,7 +145,7 @@ bool ELFDynamicLoader::load_stage_2(unsigned flags)
return true;
}
void ELFDynamicLoader::load_program_headers(const ELFImage& elf_image)
void DynamicLoader::load_program_headers(const Image& elf_image)
{
Vector<ProgramHeaderRegion> program_headers;
@ -152,7 +154,7 @@ void ELFDynamicLoader::load_program_headers(const ELFImage& elf_image)
ProgramHeaderRegion* tls_region_ptr = nullptr;
VirtualAddress dynamic_region_desired_vaddr;
elf_image.for_each_program_header([&](const ELFImage::ProgramHeader& program_header) {
elf_image.for_each_program_header([&](const Image::ProgramHeader& program_header) {
ProgramHeaderRegion new_region;
new_region.set_program_header(program_header.raw_header());
program_headers.append(move(new_region));
@ -200,7 +202,7 @@ void ELFDynamicLoader::load_program_headers(const ELFImage& elf_image)
}
}
void ELFDynamicLoader::do_relocations()
void DynamicLoader::do_relocations()
{
u32 load_base_address = m_dynamic_object->base_address().get();
@ -208,7 +210,7 @@ void ELFDynamicLoader::do_relocations()
auto main_relocation_section = m_dynamic_object->relocation_section();
main_relocation_section.for_each_relocation([&](const ELFDynamicObject::Relocation& relocation) {
main_relocation_section.for_each_relocation([&](const DynamicObject::Relocation& relocation) {
VERBOSE("====== RELOCATION %d: offset 0x%08X, type %d, symidx %08X\n", relocation.offset_in_section() / main_relocation_section.entry_size(), relocation.offset(), relocation.type(), relocation.symbol_index());
u32* patch_ptr = (u32*)(load_base_address + relocation.offset());
switch (relocation.type()) {
@ -260,7 +262,7 @@ void ELFDynamicLoader::do_relocations()
default:
// Raise the alarm! Someone needs to implement this relocation type
dbgprintf("Found a new exciting relocation type %d\n", relocation.type());
printf("ELFDynamicLoader: Found unknown relocation type %d\n", relocation.type());
printf("DynamicLoader: Found unknown relocation type %d\n", relocation.type());
ASSERT_NOT_REACHED();
break;
}
@ -268,7 +270,7 @@ void ELFDynamicLoader::do_relocations()
});
// Handle PLT Global offset table relocations.
m_dynamic_object->plt_relocation_section().for_each_relocation([&](const ELFDynamicObject::Relocation& relocation) {
m_dynamic_object->plt_relocation_section().for_each_relocation([&](const DynamicObject::Relocation& relocation) {
// FIXME: Or BIND_NOW flag passed in?
if (m_dynamic_object->must_bind_now() || s_always_bind_now) {
// Eagerly BIND_NOW the PLT entries, doing all the symbol looking goodness
@ -294,7 +296,7 @@ void ELFDynamicLoader::do_relocations()
// Defined in <arch>/plt_trampoline.S
extern "C" void _plt_trampoline(void) __attribute__((visibility("hidden")));
void ELFDynamicLoader::setup_plt_trampoline()
void DynamicLoader::setup_plt_trampoline()
{
VirtualAddress got_address = m_dynamic_object->plt_got_base_address();
@ -308,13 +310,13 @@ void ELFDynamicLoader::setup_plt_trampoline()
}
// Called from our ASM routine _plt_trampoline
extern "C" Elf32_Addr _fixup_plt_entry(ELFDynamicLoader* object, u32 relocation_offset)
extern "C" Elf32_Addr _fixup_plt_entry(DynamicLoader* object, u32 relocation_offset)
{
return object->patch_plt_entry(relocation_offset);
}
// offset is in PLT relocation table
Elf32_Addr ELFDynamicLoader::patch_plt_entry(u32 relocation_offset)
Elf32_Addr DynamicLoader::patch_plt_entry(u32 relocation_offset)
{
auto relocation = m_dynamic_object->plt_relocation_section().relocation_at_offset(relocation_offset);
@ -325,14 +327,14 @@ Elf32_Addr ELFDynamicLoader::patch_plt_entry(u32 relocation_offset)
u8* relocation_address = relocation.address().as_ptr();
u32 symbol_location = sym.address().get();
VERBOSE("ELFDynamicLoader: Jump slot relocation: putting %s (%p) into PLT at %p\n", sym.name(), symbol_location, relocation_address);
VERBOSE("DynamicLoader: Jump slot relocation: putting %s (%p) into PLT at %p\n", sym.name(), symbol_location, relocation_address);
*(u32*)relocation_address = symbol_location;
return symbol_location;
}
void ELFDynamicLoader::call_object_init_functions()
void DynamicLoader::call_object_init_functions()
{
typedef void (*InitFunc)();
auto init_function = (InitFunc)(m_dynamic_object->init_section().address().as_ptr());
@ -359,7 +361,7 @@ void ELFDynamicLoader::call_object_init_functions()
}
}
u32 ELFDynamicLoader::ProgramHeaderRegion::mmap_prot() const
u32 DynamicLoader::ProgramHeaderRegion::mmap_prot() const
{
int prot = 0;
prot |= is_executable() ? PROT_EXEC : 0;
@ -367,3 +369,5 @@ u32 ELFDynamicLoader::ProgramHeaderRegion::mmap_prot() const
prot |= is_writable() ? PROT_WRITE : 0;
return prot;
}
} // end namespace ELF

View file

@ -30,22 +30,24 @@
#include <AK/OwnPtr.h>
#include <AK/RefCounted.h>
#include <AK/String.h>
#include <LibELF/ELFDynamicObject.h>
#include <LibELF/ELFImage.h>
#include <LibELF/DynamicObject.h>
#include <LibELF/Image.h>
#include <LibELF/exec_elf.h>
#include <sys/mman.h>
namespace ELF {
#define ALIGN_ROUND_UP(x, align) ((((size_t)(x)) + align - 1) & (~(align - 1)))
class ELFDynamicLoader : public RefCounted<ELFDynamicLoader> {
class DynamicLoader : public RefCounted<DynamicLoader> {
public:
static NonnullRefPtr<ELFDynamicLoader> construct(const char* filename, int fd, size_t file_size);
static NonnullRefPtr<DynamicLoader> construct(const char* filename, int fd, size_t file_size);
~ELFDynamicLoader();
~DynamicLoader();
bool is_valid() const { return m_valid; }
// Load a full ELF image from file into the current process and create an ELFDynamicObject
// Load a full ELF image from file into the current process and create an DynamicObject
// from the SHT_DYNAMIC in the file.
bool load_from_image(unsigned flags);
@ -89,11 +91,11 @@ private:
Elf32_Phdr m_program_header; // Explictly a copy of the PHDR in the image
};
explicit ELFDynamicLoader(const char* filename, int fd, size_t file_size);
explicit ELFDynamicLoader(Elf32_Dyn* dynamic_location, Elf32_Addr load_address);
explicit DynamicLoader(const char* filename, int fd, size_t file_size);
explicit DynamicLoader(Elf32_Dyn* dynamic_location, Elf32_Addr load_address);
// Stage 1
void load_program_headers(const ELFImage& elf_image);
void load_program_headers(const Image& elf_image);
// Stage 2
void do_relocations();
@ -106,7 +108,7 @@ private:
void* m_file_mapping { nullptr };
bool m_valid { true };
OwnPtr<ELFDynamicObject> m_dynamic_object;
OwnPtr<DynamicObject> m_dynamic_object;
VirtualAddress m_text_segment_load_address;
size_t m_text_segment_size;
@ -114,3 +116,5 @@ private:
VirtualAddress m_tls_segment_address;
VirtualAddress m_dynamic_section_address;
};
} // end namespace ELF

View file

@ -26,31 +26,33 @@
#include <AK/String.h>
#include <AK/StringBuilder.h>
#include <LibELF/ELFDynamicObject.h>
#include <LibELF/DynamicObject.h>
#include <LibELF/exec_elf.h>
#include <stdio.h>
#include <string.h>
namespace ELF {
static const char* name_for_dtag(Elf32_Sword d_tag);
ELFDynamicObject::ELFDynamicObject(VirtualAddress base_address, VirtualAddress dynamic_section_addresss)
DynamicObject::DynamicObject(VirtualAddress base_address, VirtualAddress dynamic_section_addresss)
: m_base_address(base_address)
, m_dynamic_address(dynamic_section_addresss)
{
parse();
}
ELFDynamicObject::~ELFDynamicObject()
DynamicObject::~DynamicObject()
{
}
void ELFDynamicObject::dump() const
void DynamicObject::dump() const
{
StringBuilder builder;
builder.append("\nd_tag tag_name value\n");
size_t num_dynamic_sections = 0;
for_each_dynamic_entry([&](const ELFDynamicObject::DynamicEntry& entry) {
for_each_dynamic_entry([&](const DynamicObject::DynamicEntry& entry) {
String name_field = String::format("(%s)", name_for_dtag(entry.tag()));
builder.appendf("0x%08X %-17s0x%X\n", entry.tag(), name_field.characters(), entry.val());
num_dynamic_sections++;
@ -61,7 +63,7 @@ void ELFDynamicObject::dump() const
dbgprintf(builder.to_string().characters());
}
void ELFDynamicObject::parse()
void DynamicObject::parse()
{
for_each_dynamic_entry([&](const DynamicEntry& entry) {
switch (entry.tag()) {
@ -134,8 +136,8 @@ void ELFDynamicObject::parse()
m_dt_flags |= DF_TEXTREL; // This tag seems to exist for legacy reasons only?
break;
default:
dbgprintf("ELFDynamicObject: DYNAMIC tag handling not implemented for DT_%s\n", name_for_dtag(entry.tag()));
printf("ELFDynamicObject: DYNAMIC tag handling not implemented for DT_%s\n", name_for_dtag(entry.tag()));
dbgprintf("DynamicObject: DYNAMIC tag handling not implemented for DT_%s\n", name_for_dtag(entry.tag()));
printf("DynamicObject: DYNAMIC tag handling not implemented for DT_%s\n", name_for_dtag(entry.tag()));
ASSERT_NOT_REACHED(); // FIXME: Maybe just break out here and return false?
break;
}
@ -147,7 +149,7 @@ void ELFDynamicObject::parse()
m_symbol_count = num_hash_chains;
}
const ELFDynamicObject::Relocation ELFDynamicObject::RelocationSection::relocation(unsigned index) const
const DynamicObject::Relocation DynamicObject::RelocationSection::relocation(unsigned index) const
{
ASSERT(index < entry_count());
unsigned offset_in_section = index * entry_size();
@ -155,56 +157,56 @@ const ELFDynamicObject::Relocation ELFDynamicObject::RelocationSection::relocati
return Relocation(m_dynamic, *relocation_address, offset_in_section);
}
const ELFDynamicObject::Relocation ELFDynamicObject::RelocationSection::relocation_at_offset(unsigned offset) const
const DynamicObject::Relocation DynamicObject::RelocationSection::relocation_at_offset(unsigned offset) const
{
ASSERT(offset <= (m_section_size_bytes - m_entry_size));
auto relocation_address = (Elf32_Rel*)address().offset(offset).as_ptr();
return Relocation(m_dynamic, *relocation_address, offset);
}
const ELFDynamicObject::Symbol ELFDynamicObject::symbol(unsigned index) const
const DynamicObject::Symbol DynamicObject::symbol(unsigned index) const
{
auto symbol_section = Section(*this, m_symbol_table_offset, (m_symbol_count * m_size_of_symbol_table_entry), m_size_of_symbol_table_entry, "DT_SYMTAB");
auto symbol_entry = (Elf32_Sym*)symbol_section.address().offset(index * symbol_section.entry_size()).as_ptr();
return Symbol(*this, index, *symbol_entry);
}
const ELFDynamicObject::Section ELFDynamicObject::init_section() const
const DynamicObject::Section DynamicObject::init_section() const
{
return Section(*this, m_init_offset, sizeof(void (*)()), sizeof(void (*)()), "DT_INIT");
}
const ELFDynamicObject::Section ELFDynamicObject::fini_section() const
const DynamicObject::Section DynamicObject::fini_section() const
{
return Section(*this, m_fini_offset, sizeof(void (*)()), sizeof(void (*)()), "DT_FINI");
}
const ELFDynamicObject::Section ELFDynamicObject::init_array_section() const
const DynamicObject::Section DynamicObject::init_array_section() const
{
return Section(*this, m_init_array_offset, m_init_array_size, sizeof(void (*)()), "DT_INIT_ARRAY");
}
const ELFDynamicObject::Section ELFDynamicObject::fini_array_section() const
const DynamicObject::Section DynamicObject::fini_array_section() const
{
return Section(*this, m_fini_array_offset, m_fini_array_size, sizeof(void (*)()), "DT_FINI_ARRAY");
}
const ELFDynamicObject::HashSection ELFDynamicObject::hash_section() const
const DynamicObject::HashSection DynamicObject::hash_section() const
{
return HashSection(Section(*this, m_hash_table_offset, 0, 0, "DT_HASH"), HashType::SYSV);
}
const ELFDynamicObject::RelocationSection ELFDynamicObject::relocation_section() const
const DynamicObject::RelocationSection DynamicObject::relocation_section() const
{
return RelocationSection(Section(*this, m_relocation_table_offset, m_size_of_relocation_table, m_size_of_relocation_entry, "DT_REL"));
}
const ELFDynamicObject::RelocationSection ELFDynamicObject::plt_relocation_section() const
const DynamicObject::RelocationSection DynamicObject::plt_relocation_section() const
{
return RelocationSection(Section(*this, m_plt_relocation_offset_location, m_size_of_plt_relocation_entry_list, m_size_of_relocation_entry, "DT_JMPREL"));
}
u32 ELFDynamicObject::HashSection::calculate_elf_hash(const char* name) const
u32 DynamicObject::HashSection::calculate_elf_hash(const char* name) const
{
// SYSV ELF hash algorithm
// Note that the GNU HASH algorithm has less collisions
@ -226,13 +228,13 @@ u32 ELFDynamicObject::HashSection::calculate_elf_hash(const char* name) const
return hash;
}
u32 ELFDynamicObject::HashSection::calculate_gnu_hash(const char*) const
u32 DynamicObject::HashSection::calculate_gnu_hash(const char*) const
{
// FIXME: Implement the GNU hash algorithm
ASSERT_NOT_REACHED();
}
const ELFDynamicObject::Symbol ELFDynamicObject::HashSection::lookup_symbol(const char* name) const
const DynamicObject::Symbol DynamicObject::HashSection::lookup_symbol(const char* name) const
{
// FIXME: If we enable gnu hash in the compiler, we should use that here instead
// The algo is way better with less collisions
@ -262,7 +264,7 @@ const ELFDynamicObject::Symbol ELFDynamicObject::HashSection::lookup_symbol(cons
return m_dynamic.the_undefined_symbol();
}
const char* ELFDynamicObject::symbol_string_table_string(Elf32_Word index) const
const char* DynamicObject::symbol_string_table_string(Elf32_Word index) const
{
return (const char*)base_address().offset(m_string_table_offset + index).as_ptr();
}
@ -358,3 +360,5 @@ static const char* name_for_dtag(Elf32_Sword d_tag)
return "??";
}
}
} // end namespace ELF

View file

@ -30,10 +30,12 @@
#include <LibBareMetal/Memory/VirtualAddress.h>
#include <LibELF/exec_elf.h>
class ELFDynamicObject {
namespace ELF {
class DynamicObject {
public:
explicit ELFDynamicObject(VirtualAddress base_address, VirtualAddress dynamic_section_address);
~ELFDynamicObject();
explicit DynamicObject(VirtualAddress base_address, VirtualAddress dynamic_section_address);
~DynamicObject();
void dump() const;
class DynamicEntry;
@ -62,7 +64,7 @@ public:
class Symbol {
public:
Symbol(const ELFDynamicObject& dynamic, unsigned index, const Elf32_Sym& sym)
Symbol(const DynamicObject& dynamic, unsigned index, const Elf32_Sym& sym)
: m_dynamic(dynamic)
, m_sym(sym)
, m_index(index)
@ -82,14 +84,14 @@ public:
VirtualAddress address() const { return m_dynamic.base_address().offset(value()); }
private:
const ELFDynamicObject& m_dynamic;
const DynamicObject& m_dynamic;
const Elf32_Sym& m_sym;
const unsigned m_index;
};
class Section {
public:
Section(const ELFDynamicObject& dynamic, unsigned section_offset, unsigned section_size_bytes, unsigned entry_size, const char* name)
Section(const DynamicObject& dynamic, unsigned section_offset, unsigned section_size_bytes, unsigned entry_size, const char* name)
: m_dynamic(dynamic)
, m_section_offset(section_offset)
, m_section_size_bytes(section_size_bytes)
@ -109,7 +111,7 @@ public:
protected:
friend class RelocationSection;
friend class HashSection;
const ELFDynamicObject& m_dynamic;
const DynamicObject& m_dynamic;
unsigned m_section_offset;
unsigned m_section_size_bytes;
unsigned m_entry_size;
@ -131,7 +133,7 @@ public:
class Relocation {
public:
Relocation(const ELFDynamicObject& dynamic, const Elf32_Rel& rel, unsigned offset_in_section)
Relocation(const DynamicObject& dynamic, const Elf32_Rel& rel, unsigned offset_in_section)
: m_dynamic(dynamic)
, m_rel(rel)
, m_offset_in_section(offset_in_section)
@ -148,7 +150,7 @@ public:
VirtualAddress address() const { return m_dynamic.base_address().offset(offset()); }
private:
const ELFDynamicObject& m_dynamic;
const DynamicObject& m_dynamic;
const Elf32_Rel& m_rel;
const unsigned m_offset_in_section;
};
@ -261,7 +263,7 @@ private:
};
template<typename F>
inline void ELFDynamicObject::RelocationSection::for_each_relocation(F func) const
inline void DynamicObject::RelocationSection::for_each_relocation(F func) const
{
for (unsigned i = 0; i < relocation_count(); ++i) {
if (func(relocation(i)) == IterationDecision::Break)
@ -270,7 +272,7 @@ inline void ELFDynamicObject::RelocationSection::for_each_relocation(F func) con
}
template<typename F>
inline void ELFDynamicObject::for_each_symbol(F func) const
inline void DynamicObject::for_each_symbol(F func) const
{
for (unsigned i = 0; i < symbol_count(); ++i) {
if (func(symbol(i)) == IterationDecision::Break)
@ -279,7 +281,7 @@ inline void ELFDynamicObject::for_each_symbol(F func) const
}
template<typename F>
inline void ELFDynamicObject::for_each_dynamic_entry(F func) const
inline void DynamicObject::for_each_dynamic_entry(F func) const
{
auto* dyns = reinterpret_cast<const Elf32_Dyn*>(m_dynamic_address.as_ptr());
for (unsigned i = 0;; ++i) {
@ -290,3 +292,5 @@ inline void ELFDynamicObject::for_each_dynamic_entry(F func) const
break;
}
}
} // end namespace ELF

View file

@ -27,16 +27,18 @@
#include <AK/Memory.h>
#include <AK/StringBuilder.h>
#include <AK/StringView.h>
#include <LibELF/ELFImage.h>
#include <LibELF/Image.h>
ELFImage::ELFImage(const u8* buffer, size_t size)
namespace ELF {
Image::Image(const u8* buffer, size_t size)
: m_buffer(buffer)
, m_size(size)
{
m_valid = parse();
}
ELFImage::~ELFImage()
Image::~Image()
{
}
@ -58,7 +60,7 @@ static const char* object_file_type_to_string(Elf32_Half type)
}
}
StringView ELFImage::section_index_to_string(unsigned index) const
StringView Image::section_index_to_string(unsigned index) const
{
if (index == SHN_UNDEF)
return "Undefined";
@ -67,14 +69,14 @@ StringView ELFImage::section_index_to_string(unsigned index) const
return section(index).name();
}
unsigned ELFImage::symbol_count() const
unsigned Image::symbol_count() const
{
return section(m_symbol_table_section_index).entry_count();
}
void ELFImage::dump() const
void Image::dump() const
{
dbgprintf("ELFImage{%p} {\n", this);
dbgprintf("Image{%p} {\n", this);
dbgprintf(" is_valid: %u\n", is_valid());
if (!is_valid()) {
@ -124,20 +126,20 @@ void ELFImage::dump() const
dbgprintf("}\n");
}
unsigned ELFImage::section_count() const
unsigned Image::section_count() const
{
return header().e_shnum;
}
unsigned ELFImage::program_header_count() const
unsigned Image::program_header_count() const
{
return header().e_phnum;
}
bool ELFImage::parse()
bool Image::parse()
{
if (!validate_elf_header(header(), m_size)) {
dbgputstr("ELFImage::parse(): ELF Header not valid\n");
dbgputstr("Image::parse(): ELF Header not valid\n");
return false;
}
@ -163,14 +165,14 @@ bool ELFImage::parse()
return true;
}
StringView ELFImage::table_string(unsigned table_index, unsigned offset) const
StringView Image::table_string(unsigned table_index, unsigned offset) const
{
auto& sh = section_header(table_index);
if (sh.sh_type != SHT_STRTAB)
return nullptr;
size_t computed_offset = sh.sh_offset + offset;
if (computed_offset >= m_size) {
dbgprintf("SHENANIGANS! ELFImage::table_string() computed offset outside image.\n");
dbgprintf("SHENANIGANS! Image::table_string() computed offset outside image.\n");
return {};
}
size_t max_length = m_size - computed_offset;
@ -178,65 +180,65 @@ StringView ELFImage::table_string(unsigned table_index, unsigned offset) const
return { raw_data(sh.sh_offset + offset), length };
}
StringView ELFImage::section_header_table_string(unsigned offset) const
StringView Image::section_header_table_string(unsigned offset) const
{
return table_string(header().e_shstrndx, offset);
}
StringView ELFImage::table_string(unsigned offset) const
StringView Image::table_string(unsigned offset) const
{
return table_string(m_string_table_section_index, offset);
}
const char* ELFImage::raw_data(unsigned offset) const
const char* Image::raw_data(unsigned offset) const
{
return reinterpret_cast<const char*>(m_buffer) + offset;
}
const Elf32_Ehdr& ELFImage::header() const
const Elf32_Ehdr& Image::header() const
{
return *reinterpret_cast<const Elf32_Ehdr*>(raw_data(0));
}
const Elf32_Phdr& ELFImage::program_header_internal(unsigned index) const
const Elf32_Phdr& Image::program_header_internal(unsigned index) const
{
ASSERT(index < header().e_phnum);
return *reinterpret_cast<const Elf32_Phdr*>(raw_data(header().e_phoff + (index * sizeof(Elf32_Phdr))));
}
const Elf32_Shdr& ELFImage::section_header(unsigned index) const
const Elf32_Shdr& Image::section_header(unsigned index) const
{
ASSERT(index < header().e_shnum);
return *reinterpret_cast<const Elf32_Shdr*>(raw_data(header().e_shoff + (index * header().e_shentsize)));
}
const ELFImage::Symbol ELFImage::symbol(unsigned index) const
const Image::Symbol Image::symbol(unsigned index) const
{
ASSERT(index < symbol_count());
auto* raw_syms = reinterpret_cast<const Elf32_Sym*>(raw_data(section(m_symbol_table_section_index).offset()));
return Symbol(*this, index, raw_syms[index]);
}
const ELFImage::Section ELFImage::section(unsigned index) const
const Image::Section Image::section(unsigned index) const
{
ASSERT(index < section_count());
return Section(*this, index);
}
const ELFImage::ProgramHeader ELFImage::program_header(unsigned index) const
const Image::ProgramHeader Image::program_header(unsigned index) const
{
ASSERT(index < program_header_count());
return ProgramHeader(*this, index);
}
const ELFImage::Relocation ELFImage::RelocationSection::relocation(unsigned index) const
const Image::Relocation Image::RelocationSection::relocation(unsigned index) const
{
ASSERT(index < relocation_count());
auto* rels = reinterpret_cast<const Elf32_Rel*>(m_image.raw_data(offset()));
return Relocation(m_image, rels[index]);
}
const ELFImage::RelocationSection ELFImage::Section::relocations() const
const Image::RelocationSection Image::Section::relocations() const
{
StringBuilder builder;
builder.append(".rel");
@ -246,20 +248,20 @@ const ELFImage::RelocationSection ELFImage::Section::relocations() const
if (relocation_section.type() != SHT_REL)
return static_cast<const RelocationSection>(m_image.section(0));
#ifdef ELFIMAGE_DEBUG
#ifdef Image_DEBUG
dbgprintf("Found relocations for %s in %s\n", name(), relocation_section.name());
#endif
return static_cast<const RelocationSection>(relocation_section);
}
const ELFImage::Section ELFImage::lookup_section(const String& name) const
const Image::Section Image::lookup_section(const String& name) const
{
if (auto it = m_sections.find(name); it != m_sections.end())
return section((*it).value);
return section(0);
}
bool ELFImage::validate_elf_header(const Elf32_Ehdr& elf_header, size_t file_size)
bool Image::validate_elf_header(const Elf32_Ehdr& elf_header, size_t file_size)
{
if (!IS_ELF(elf_header)) {
dbgputstr("File is not an ELF file.\n");
@ -358,7 +360,7 @@ bool ELFImage::validate_elf_header(const Elf32_Ehdr& elf_header, size_t file_siz
return true;
}
bool ELFImage::validate_program_headers(const Elf32_Ehdr& elf_header, size_t file_size, u8* buffer, size_t buffer_size, String& interpreter_path)
bool Image::validate_program_headers(const Elf32_Ehdr& elf_header, size_t file_size, u8* buffer, size_t buffer_size, String& interpreter_path)
{
// Can we actually parse all the program headers in the given buffer?
size_t end_of_last_program_header = elf_header.e_phoff + (elf_header.e_phnum * elf_header.e_phentsize);
@ -414,8 +416,10 @@ bool ELFImage::validate_program_headers(const Elf32_Ehdr& elf_header, size_t fil
return true;
}
StringView ELFImage::Symbol::raw_data() const
StringView Image::Symbol::raw_data() const
{
auto& section = this->section();
return { section.raw_data() + (value() - section.address()), size() };
}
} // end namespace ELF

View file

@ -32,10 +32,12 @@
#include <LibBareMetal/Memory/VirtualAddress.h>
#include <LibELF/exec_elf.h>
class ELFImage {
namespace ELF {
class Image {
public:
explicit ELFImage(const u8*, size_t);
~ELFImage();
explicit Image(const u8*, size_t);
~Image();
void dump() const;
bool is_valid() const { return m_valid; }
bool parse();
@ -56,7 +58,7 @@ public:
class Symbol {
public:
Symbol(const ELFImage& image, unsigned index, const Elf32_Sym& sym)
Symbol(const Image& image, unsigned index, const Elf32_Sym& sym)
: m_image(image)
, m_sym(sym)
, m_index(index)
@ -76,14 +78,14 @@ public:
StringView raw_data() const;
private:
const ELFImage& m_image;
const Image& m_image;
const Elf32_Sym& m_sym;
const unsigned m_index;
};
class ProgramHeader {
public:
ProgramHeader(const ELFImage& image, unsigned program_header_index)
ProgramHeader(const Image& image, unsigned program_header_index)
: m_image(image)
, m_program_header(image.program_header_internal(program_header_index))
, m_program_header_index(program_header_index)
@ -106,14 +108,14 @@ public:
Elf32_Phdr raw_header() const { return m_program_header; }
private:
const ELFImage& m_image;
const Image& m_image;
const Elf32_Phdr& m_program_header;
unsigned m_program_header_index { 0 };
};
class Section {
public:
Section(const ELFImage& image, unsigned sectionIndex)
Section(const Image& image, unsigned sectionIndex)
: m_image(image)
, m_section_header(image.section_header(sectionIndex))
, m_section_index(sectionIndex)
@ -137,7 +139,7 @@ public:
protected:
friend class RelocationSection;
const ELFImage& m_image;
const Image& m_image;
const Elf32_Shdr& m_section_header;
unsigned m_section_index;
};
@ -156,7 +158,7 @@ public:
class Relocation {
public:
Relocation(const ELFImage& image, const Elf32_Rel& rel)
Relocation(const Image& image, const Elf32_Rel& rel)
: m_image(image)
, m_rel(rel)
{
@ -170,7 +172,7 @@ public:
const Symbol symbol() const { return m_image.symbol(symbol_index()); }
private:
const ELFImage& m_image;
const Image& m_image;
const Elf32_Rel& m_rel;
};
@ -224,7 +226,7 @@ private:
};
template<typename F>
inline void ELFImage::for_each_section(F func) const
inline void Image::for_each_section(F func) const
{
auto section_count = this->section_count();
for (unsigned i = 0; i < section_count; ++i)
@ -232,7 +234,7 @@ inline void ELFImage::for_each_section(F func) const
}
template<typename F>
inline void ELFImage::for_each_section_of_type(unsigned type, F func) const
inline void Image::for_each_section_of_type(unsigned type, F func) const
{
auto section_count = this->section_count();
for (unsigned i = 0; i < section_count; ++i) {
@ -245,7 +247,7 @@ inline void ELFImage::for_each_section_of_type(unsigned type, F func) const
}
template<typename F>
inline void ELFImage::RelocationSection::for_each_relocation(F func) const
inline void Image::RelocationSection::for_each_relocation(F func) const
{
auto relocation_count = this->relocation_count();
for (unsigned i = 0; i < relocation_count; ++i) {
@ -255,7 +257,7 @@ inline void ELFImage::RelocationSection::for_each_relocation(F func) const
}
template<typename F>
inline void ELFImage::for_each_symbol(F func) const
inline void Image::for_each_symbol(F func) const
{
auto symbol_count = this->symbol_count();
for (unsigned i = 0; i < symbol_count; ++i) {
@ -265,9 +267,11 @@ inline void ELFImage::for_each_symbol(F func) const
}
template<typename F>
inline void ELFImage::for_each_program_header(F func) const
inline void Image::for_each_program_header(F func) const
{
auto program_header_count = this->program_header_count();
for (unsigned i = 0; i < program_header_count; ++i)
func(program_header(i));
}
} // end namespace ELF

View file

@ -24,7 +24,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ELFLoader.h"
#include "Loader.h"
#include <AK/Demangle.h>
#include <AK/Memory.h>
#include <AK/QuickSort.h>
@ -36,21 +36,23 @@
# define do_memcpy memcpy
#endif
//#define ELFLOADER_DEBUG
//#define Loader_DEBUG
ELFLoader::ELFLoader(const u8* buffer, size_t size)
namespace ELF {
Loader::Loader(const u8* buffer, size_t size)
: m_image(buffer, size)
{
m_symbol_count = m_image.symbol_count();
}
ELFLoader::~ELFLoader()
Loader::~Loader()
{
}
bool ELFLoader::load()
bool Loader::load()
{
#ifdef ELFLOADER_DEBUG
#ifdef Loader_DEBUG
m_image.dump();
#endif
if (!m_image.is_valid())
@ -62,10 +64,10 @@ bool ELFLoader::load()
return true;
}
bool ELFLoader::layout()
bool Loader::layout()
{
bool failed = false;
m_image.for_each_program_header([&](const ELFImage::ProgramHeader& program_header) {
m_image.for_each_program_header([&](const Image::ProgramHeader& program_header) {
if (program_header.type() == PT_TLS) {
#ifdef KERNEL
auto* tls_image = tls_section_hook(program_header.size_in_memory(), program_header.alignment());
@ -84,7 +86,7 @@ bool ELFLoader::layout()
}
if (program_header.type() != PT_LOAD)
return;
#ifdef ELFLOADER_DEBUG
#ifdef Loader_DEBUG
kprintf("PH: V%p %u r:%u w:%u\n", program_header.vaddr().get(), program_header.size_in_memory(), program_header.is_readable(), program_header.is_writable());
#endif
#ifdef KERNEL
@ -134,10 +136,10 @@ bool ELFLoader::layout()
return !failed;
}
char* ELFLoader::symbol_ptr(const char* name)
char* Loader::symbol_ptr(const char* name)
{
char* found_ptr = nullptr;
m_image.for_each_symbol([&](const ELFImage::Symbol symbol) {
m_image.for_each_symbol([&](const Image::Symbol symbol) {
if (symbol.type() != STT_FUNC)
return IterationDecision::Continue;
if (symbol.name() == name)
@ -152,7 +154,7 @@ char* ELFLoader::symbol_ptr(const char* name)
}
#ifndef KERNEL
Optional<ELFImage::Symbol> ELFLoader::find_symbol(u32 address, u32* out_offset) const
Optional<Image::Symbol> Loader::find_symbol(u32 address, u32* out_offset) const
{
if (!m_symbol_count)
return {};
@ -201,7 +203,7 @@ Optional<ELFImage::Symbol> ELFLoader::find_symbol(u32 address, u32* out_offset)
}
#endif
String ELFLoader::symbolicate(u32 address, u32* out_offset) const
String Loader::symbolicate(u32 address, u32* out_offset) const
{
if (!m_symbol_count) {
if (out_offset)
@ -266,3 +268,5 @@ String ELFLoader::symbolicate(u32 address, u32* out_offset) const
*out_offset = 0;
return "??";
}
} // end namespace ELF

View file

@ -31,7 +31,7 @@
#include <AK/OwnPtr.h>
#include <AK/StringView.h>
#include <AK/Vector.h>
#include <LibELF/ELFImage.h>
#include <LibELF/Image.h>
#ifdef KERNEL
# include <LibBareMetal/Memory/VirtualAddress.h>
@ -40,10 +40,12 @@ class Region;
}
#endif
class ELFLoader {
namespace ELF {
class Loader {
public:
explicit ELFLoader(const u8*, size_t);
~ELFLoader();
explicit Loader(const u8*, size_t);
~Loader();
bool load();
#if defined(KERNEL)
@ -57,13 +59,13 @@ public:
bool has_symbols() const { return m_symbol_count; }
String symbolicate(u32 address, u32* offset = nullptr) const;
Optional<ELFImage::Symbol> find_symbol(u32 address, u32* offset = nullptr) const;
Optional<Image::Symbol> find_symbol(u32 address, u32* offset = nullptr) const;
private:
bool layout();
bool perform_relocations();
void* lookup(const ELFImage::Symbol&);
char* area_for_section(const ELFImage::Section&);
void* lookup(const ELF::Image::Symbol&);
char* area_for_section(const ELF::Image::Section&);
char* area_for_section_name(const char*);
struct PtrAndSize {
@ -77,7 +79,7 @@ private:
char* ptr { nullptr };
unsigned size { 0 };
};
ELFImage m_image;
Image m_image;
size_t m_symbol_count { 0 };
@ -86,7 +88,7 @@ private:
StringView name;
#ifndef KERNEL
String demangled_name;
Optional<ELFImage::Symbol> symbol;
Optional<Image::Symbol> symbol;
#endif
};
#ifdef KERNEL
@ -95,3 +97,5 @@ private:
mutable Vector<SortedSymbol> m_sorted_symbols;
#endif
};
} // end namespace ELF