1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 06:38:10 +00:00

Loader: Add dynamic loader program

The dynamic loader exists as /usr/lib/Loader.so and is loaded by the
kernel when ET_DYN programs are executed.

The dynamic loader is responsible for loading the dependencies of the
main program, allocating TLS storage, preparing all loaded objects for
execution and finally jumping to the entry of the main program.
This commit is contained in:
Itamar 2020-10-10 18:17:49 +03:00 committed by Andreas Kling
parent 781aa424a9
commit 07b4957361
18 changed files with 962 additions and 104 deletions

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2019-2020, Andrew Kaster <andrewdkaster@gmail.com>
* Copyright (c) 2020, Itamar S. <itamar8910@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -142,6 +143,13 @@ void DynamicObject::parse()
m_soname_index = entry.val();
m_has_soname = true;
break;
case DT_DEBUG:
break;
case DT_FLAGS_1:
break;
case DT_NEEDED:
// We handle these in for_each_needed_library
break;
default:
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()));
@ -151,6 +159,13 @@ void DynamicObject::parse()
return IterationDecision::Continue;
});
if (!m_size_of_relocation_entry) {
// TODO: FIXME, this shouldn't be hardcoded
// The reason we need this here is the for some reason, when there only PLT relocations, the compiler
// doesn't insert a 'PLTRELSZ' entry to the dynamic section
m_size_of_relocation_entry = sizeof(Elf32_Rel);
}
auto hash_section_address = hash_section().address().as_ptr();
auto num_hash_chains = ((u32*)hash_section_address)[1];
m_symbol_count = num_hash_chains;
@ -268,7 +283,7 @@ const DynamicObject::Symbol DynamicObject::HashSection::lookup_symbol(const char
return symbol;
}
}
return m_dynamic.the_undefined_symbol();
return Symbol::create_undefined(m_dynamic);
}
const char* DynamicObject::symbol_string_table_string(Elf32_Word index) const
@ -276,6 +291,12 @@ const char* DynamicObject::symbol_string_table_string(Elf32_Word index) const
return (const char*)base_address().offset(m_string_table_offset + index).as_ptr();
}
DynamicObject::InitializationFunction DynamicObject::init_section_function() const
{
ASSERT(has_init_section());
return (InitializationFunction)init_section().address().as_ptr();
}
static const char* name_for_dtag(Elf32_Sword d_tag)
{
switch (d_tag) {
@ -368,4 +389,17 @@ static const char* name_for_dtag(Elf32_Sword d_tag)
}
}
Optional<DynamicObject::SymbolLookupResult> DynamicObject::lookup_symbol(const char* name) const
{
auto res = hash_section().lookup_symbol(name);
if (res.is_undefined())
return {};
return SymbolLookupResult { true, res.value(), (FlatPtr)res.address().as_ptr(), this };
}
NonnullRefPtr<DynamicObject> DynamicObject::construct(VirtualAddress base_address, VirtualAddress dynamic_section_address)
{
return adopt(*new DynamicObject(base_address, dynamic_section_address));
}
} // end namespace ELF