mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 15:57:45 +00:00
Loader: Support loading non-position independent executables
This commit is contained in:
parent
0cb636078a
commit
a83a9f3a55
5 changed files with 88 additions and 41 deletions
|
@ -144,9 +144,10 @@ void* DynamicLoader::symbol_for_name(const char* name)
|
||||||
RefPtr<DynamicObject> DynamicLoader::load_from_image(unsigned flags, size_t total_tls_size)
|
RefPtr<DynamicObject> DynamicLoader::load_from_image(unsigned flags, size_t total_tls_size)
|
||||||
{
|
{
|
||||||
|
|
||||||
m_valid = m_elf_image.is_valid() && m_elf_image.is_dynamic();
|
m_valid = m_elf_image.is_valid();
|
||||||
|
|
||||||
if (!m_valid) {
|
if (!m_valid) {
|
||||||
|
dbgprintf("DynamicLoader::load_from_image failed: image is invalid\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,8 +164,10 @@ RefPtr<DynamicObject> DynamicLoader::load_from_image(unsigned flags, size_t tota
|
||||||
m_dynamic_object->m_global_symbol_lookup_func = m_global_symbol_lookup_func;
|
m_dynamic_object->m_global_symbol_lookup_func = m_global_symbol_lookup_func;
|
||||||
|
|
||||||
auto rc = load_stage_2(flags, total_tls_size);
|
auto rc = load_stage_2(flags, total_tls_size);
|
||||||
if (!rc)
|
if (!rc) {
|
||||||
|
dbgprintf("DynamicLoader::load_from_image failed at load_stage_2\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
return m_dynamic_object;
|
return m_dynamic_object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,7 +238,9 @@ void DynamicLoader::load_program_headers()
|
||||||
|
|
||||||
// Process regions in order: .text, .data, .tls
|
// Process regions in order: .text, .data, .tls
|
||||||
auto* region = text_region_ptr;
|
auto* region = text_region_ptr;
|
||||||
void* text_segment_begin = mmap_with_name(nullptr,
|
void* requested_load_address = m_elf_image.is_dynamic() ? nullptr : region->desired_load_address().as_ptr();
|
||||||
|
void* text_segment_begin = mmap_with_name(
|
||||||
|
requested_load_address,
|
||||||
region->required_load_size(),
|
region->required_load_size(),
|
||||||
region->mmap_prot(),
|
region->mmap_prot(),
|
||||||
MAP_PRIVATE,
|
MAP_PRIVATE,
|
||||||
|
@ -245,13 +250,18 @@ void DynamicLoader::load_program_headers()
|
||||||
if (MAP_FAILED == text_segment_begin) {
|
if (MAP_FAILED == text_segment_begin) {
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
ASSERT(requested_load_address == nullptr || requested_load_address == text_segment_begin);
|
||||||
m_text_segment_size = region->required_load_size();
|
m_text_segment_size = region->required_load_size();
|
||||||
m_text_segment_load_address = VirtualAddress { (FlatPtr)text_segment_begin };
|
m_text_segment_load_address = VirtualAddress { (FlatPtr)text_segment_begin };
|
||||||
|
|
||||||
m_dynamic_section_address = dynamic_region_desired_vaddr.offset(m_text_segment_load_address.get());
|
if (m_elf_image.is_dynamic())
|
||||||
|
m_dynamic_section_address = dynamic_region_desired_vaddr.offset(m_text_segment_load_address.get());
|
||||||
|
else
|
||||||
|
m_dynamic_section_address = dynamic_region_desired_vaddr;
|
||||||
|
|
||||||
region = data_region_ptr;
|
region = data_region_ptr;
|
||||||
void* data_segment_begin = mmap_with_name((u8*)text_segment_begin + m_text_segment_size,
|
void* data_segment_begin = mmap_with_name(
|
||||||
|
(u8*)text_segment_begin + m_text_segment_size,
|
||||||
region->required_load_size(),
|
region->required_load_size(),
|
||||||
region->mmap_prot(),
|
region->mmap_prot(),
|
||||||
MAP_ANONYMOUS | MAP_PRIVATE,
|
MAP_ANONYMOUS | MAP_PRIVATE,
|
||||||
|
@ -261,10 +271,14 @@ void DynamicLoader::load_program_headers()
|
||||||
if (MAP_FAILED == data_segment_begin) {
|
if (MAP_FAILED == data_segment_begin) {
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
VirtualAddress data_segment_actual_addr = region->desired_load_address().offset((FlatPtr)text_segment_begin);
|
VirtualAddress data_segment_actual_addr;
|
||||||
|
if (m_elf_image.is_dynamic()) {
|
||||||
|
data_segment_actual_addr = region->desired_load_address().offset((FlatPtr)text_segment_begin);
|
||||||
|
} else {
|
||||||
|
data_segment_actual_addr = region->desired_load_address();
|
||||||
|
}
|
||||||
memcpy(data_segment_actual_addr.as_ptr(), (u8*)m_file_mapping + region->offset(), region->size_in_image());
|
memcpy(data_segment_actual_addr.as_ptr(), (u8*)m_file_mapping + region->offset(), region->size_in_image());
|
||||||
|
// FIXME: Initialize the values in the TLS section. Currently, it is zeroed.
|
||||||
// FIXME: Initialize the values in the TLS section. Currently, it will always be zeroed.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DynamicLoader::do_relocations(size_t total_tls_size)
|
void DynamicLoader::do_relocations(size_t total_tls_size)
|
||||||
|
@ -272,7 +286,12 @@ void DynamicLoader::do_relocations(size_t total_tls_size)
|
||||||
auto main_relocation_section = m_dynamic_object->relocation_section();
|
auto main_relocation_section = m_dynamic_object->relocation_section();
|
||||||
main_relocation_section.for_each_relocation([&](ELF::DynamicObject::Relocation relocation) {
|
main_relocation_section.for_each_relocation([&](ELF::DynamicObject::Relocation relocation) {
|
||||||
VERBOSE("Relocation symbol: %s, type: %d\n", relocation.symbol().name(), relocation.type());
|
VERBOSE("Relocation symbol: %s, type: %d\n", relocation.symbol().name(), relocation.type());
|
||||||
u32* patch_ptr = (u32*)(m_dynamic_object->base_address().as_ptr() + relocation.offset());
|
FlatPtr* patch_ptr = nullptr;
|
||||||
|
if (is_dynamic())
|
||||||
|
patch_ptr = (FlatPtr*)(m_dynamic_object->base_address().as_ptr() + relocation.offset());
|
||||||
|
else
|
||||||
|
patch_ptr = (FlatPtr*)(FlatPtr)relocation.offset();
|
||||||
|
|
||||||
// VERBOSE("dynamic object name: %s\n", dynamic_object.object_name());
|
// VERBOSE("dynamic object name: %s\n", dynamic_object.object_name());
|
||||||
VERBOSE("dynamic object base address: %p\n", m_dynamic_object->base_address());
|
VERBOSE("dynamic object base address: %p\n", m_dynamic_object->base_address());
|
||||||
VERBOSE("relocation offset: 0x%x\n", relocation.offset());
|
VERBOSE("relocation offset: 0x%x\n", relocation.offset());
|
||||||
|
@ -393,13 +412,12 @@ void DynamicLoader::do_relocations(size_t total_tls_size)
|
||||||
VERBOSE("patching plt reloaction: 0x%x\n", relocation.offset_in_section());
|
VERBOSE("patching plt reloaction: 0x%x\n", relocation.offset_in_section());
|
||||||
[[maybe_unused]] auto rc = m_dynamic_object->patch_plt_entry(relocation.offset_in_section());
|
[[maybe_unused]] auto rc = m_dynamic_object->patch_plt_entry(relocation.offset_in_section());
|
||||||
} else {
|
} else {
|
||||||
// LAZY-ily bind the PLT slots by just adding the base address to the offsets stored there
|
|
||||||
// This avoids doing symbol lookup, which might be expensive
|
|
||||||
ASSERT(relocation.type() == R_386_JMP_SLOT);
|
ASSERT(relocation.type() == R_386_JMP_SLOT);
|
||||||
|
|
||||||
u8* relocation_address = relocation.address().as_ptr();
|
u8* relocation_address = relocation.address().as_ptr();
|
||||||
|
|
||||||
*(u32*)relocation_address += (FlatPtr)m_dynamic_object->base_address().as_ptr();
|
if (m_elf_image.is_dynamic())
|
||||||
|
*(u32*)relocation_address += (FlatPtr)m_dynamic_object->base_address().as_ptr();
|
||||||
}
|
}
|
||||||
return IterationDecision::Continue;
|
return IterationDecision::Continue;
|
||||||
});
|
});
|
||||||
|
|
|
@ -79,6 +79,7 @@ public:
|
||||||
void set_global_symbol_lookup_function(DynamicObject::SymbolLookupFunction func) { m_global_symbol_lookup_func = func; }
|
void set_global_symbol_lookup_function(DynamicObject::SymbolLookupFunction func) { m_global_symbol_lookup_func = func; }
|
||||||
|
|
||||||
VirtualAddress text_segment_load_address() const { return m_text_segment_load_address; }
|
VirtualAddress text_segment_load_address() const { return m_text_segment_load_address; }
|
||||||
|
bool is_dynamic() const { return m_elf_image.is_dynamic(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class ProgramHeaderRegion {
|
class ProgramHeaderRegion {
|
||||||
|
|
|
@ -50,6 +50,14 @@ DynamicObject::DynamicObject(VirtualAddress base_address, VirtualAddress dynamic
|
||||||
: m_base_address(base_address)
|
: m_base_address(base_address)
|
||||||
, m_dynamic_address(dynamic_section_addresss)
|
, m_dynamic_address(dynamic_section_addresss)
|
||||||
{
|
{
|
||||||
|
Elf32_Ehdr* header = (Elf32_Ehdr*)base_address.as_ptr();
|
||||||
|
Elf32_Phdr* pheader = (Elf32_Phdr*)(base_address.as_ptr() + header->e_phoff);
|
||||||
|
m_elf_base_address = VirtualAddress(pheader->p_vaddr - pheader->p_offset);
|
||||||
|
if (header->e_type == ET_DYN)
|
||||||
|
m_is_elf_dynamic = true;
|
||||||
|
else
|
||||||
|
m_is_elf_dynamic = false;
|
||||||
|
|
||||||
parse();
|
parse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,31 +90,31 @@ void DynamicObject::parse()
|
||||||
for_each_dynamic_entry([&](const DynamicEntry& entry) {
|
for_each_dynamic_entry([&](const DynamicEntry& entry) {
|
||||||
switch (entry.tag()) {
|
switch (entry.tag()) {
|
||||||
case DT_INIT:
|
case DT_INIT:
|
||||||
m_init_offset = entry.ptr();
|
m_init_offset = entry.ptr() - (FlatPtr)m_elf_base_address.as_ptr();
|
||||||
break;
|
break;
|
||||||
case DT_FINI:
|
case DT_FINI:
|
||||||
m_fini_offset = entry.ptr();
|
m_fini_offset = entry.ptr() - (FlatPtr)m_elf_base_address.as_ptr();
|
||||||
break;
|
break;
|
||||||
case DT_INIT_ARRAY:
|
case DT_INIT_ARRAY:
|
||||||
m_init_array_offset = entry.ptr();
|
m_init_array_offset = entry.ptr() - (FlatPtr)m_elf_base_address.as_ptr();
|
||||||
break;
|
break;
|
||||||
case DT_INIT_ARRAYSZ:
|
case DT_INIT_ARRAYSZ:
|
||||||
m_init_array_size = entry.val();
|
m_init_array_size = entry.val();
|
||||||
break;
|
break;
|
||||||
case DT_FINI_ARRAY:
|
case DT_FINI_ARRAY:
|
||||||
m_fini_array_offset = entry.ptr();
|
m_fini_array_offset = entry.ptr() - (FlatPtr)m_elf_base_address.as_ptr();
|
||||||
break;
|
break;
|
||||||
case DT_FINI_ARRAYSZ:
|
case DT_FINI_ARRAYSZ:
|
||||||
m_fini_array_size = entry.val();
|
m_fini_array_size = entry.val();
|
||||||
break;
|
break;
|
||||||
case DT_HASH:
|
case DT_HASH:
|
||||||
m_hash_table_offset = entry.ptr();
|
m_hash_table_offset = entry.ptr() - (FlatPtr)m_elf_base_address.as_ptr();
|
||||||
break;
|
break;
|
||||||
case DT_SYMTAB:
|
case DT_SYMTAB:
|
||||||
m_symbol_table_offset = entry.ptr();
|
m_symbol_table_offset = entry.ptr() - (FlatPtr)m_elf_base_address.as_ptr();
|
||||||
break;
|
break;
|
||||||
case DT_STRTAB:
|
case DT_STRTAB:
|
||||||
m_string_table_offset = entry.ptr();
|
m_string_table_offset = entry.ptr() - (FlatPtr)m_elf_base_address.as_ptr();
|
||||||
break;
|
break;
|
||||||
case DT_STRSZ:
|
case DT_STRSZ:
|
||||||
m_size_of_string_table = entry.val();
|
m_size_of_string_table = entry.val();
|
||||||
|
@ -115,7 +123,7 @@ void DynamicObject::parse()
|
||||||
m_size_of_symbol_table_entry = entry.val();
|
m_size_of_symbol_table_entry = entry.val();
|
||||||
break;
|
break;
|
||||||
case DT_PLTGOT:
|
case DT_PLTGOT:
|
||||||
m_procedure_linkage_table_offset = entry.ptr();
|
m_procedure_linkage_table_offset = entry.ptr() - (FlatPtr)m_elf_base_address.as_ptr();
|
||||||
break;
|
break;
|
||||||
case DT_PLTRELSZ:
|
case DT_PLTRELSZ:
|
||||||
m_size_of_plt_relocation_entry_list = entry.val();
|
m_size_of_plt_relocation_entry_list = entry.val();
|
||||||
|
@ -125,11 +133,11 @@ void DynamicObject::parse()
|
||||||
ASSERT(m_procedure_linkage_table_relocation_type & (DT_REL | DT_RELA));
|
ASSERT(m_procedure_linkage_table_relocation_type & (DT_REL | DT_RELA));
|
||||||
break;
|
break;
|
||||||
case DT_JMPREL:
|
case DT_JMPREL:
|
||||||
m_plt_relocation_offset_location = entry.ptr();
|
m_plt_relocation_offset_location = entry.ptr() - (FlatPtr)m_elf_base_address.as_ptr();
|
||||||
break;
|
break;
|
||||||
case DT_RELA:
|
case DT_RELA:
|
||||||
case DT_REL:
|
case DT_REL:
|
||||||
m_relocation_table_offset = entry.ptr();
|
m_relocation_table_offset = entry.ptr() - (FlatPtr)m_elf_base_address.as_ptr();
|
||||||
break;
|
break;
|
||||||
case DT_RELASZ:
|
case DT_RELASZ:
|
||||||
case DT_RELSZ:
|
case DT_RELSZ:
|
||||||
|
@ -171,12 +179,13 @@ void DynamicObject::parse()
|
||||||
|
|
||||||
if (!m_size_of_relocation_entry) {
|
if (!m_size_of_relocation_entry) {
|
||||||
// TODO: FIXME, this shouldn't be hardcoded
|
// 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
|
// The reason we need this here is that for some reason, when there only PLT relocations, the compiler
|
||||||
// doesn't insert a 'PLTRELSZ' entry to the dynamic section
|
// doesn't insert a 'PLTRELSZ' entry to the dynamic section
|
||||||
m_size_of_relocation_entry = sizeof(Elf32_Rel);
|
m_size_of_relocation_entry = sizeof(Elf32_Rel);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto hash_section_address = hash_section().address().as_ptr();
|
auto hash_section_address = hash_section().address().as_ptr();
|
||||||
|
// TODO: consider base address - it might not be zero
|
||||||
auto num_hash_chains = ((u32*)hash_section_address)[1];
|
auto num_hash_chains = ((u32*)hash_section_address)[1];
|
||||||
m_symbol_count = num_hash_chains;
|
m_symbol_count = num_hash_chains;
|
||||||
}
|
}
|
||||||
|
@ -287,9 +296,7 @@ const DynamicObject::Symbol DynamicObject::HashSection::lookup_symbol(const char
|
||||||
for (u32 i = buckets[hash_value % num_buckets]; i; i = chains[i]) {
|
for (u32 i = buckets[hash_value % num_buckets]; i; i = chains[i]) {
|
||||||
auto symbol = m_dynamic.symbol(i);
|
auto symbol = m_dynamic.symbol(i);
|
||||||
if (strcmp(name, symbol.name()) == 0) {
|
if (strcmp(name, symbol.name()) == 0) {
|
||||||
#ifdef DYNAMIC_LOAD_DEBUG
|
VERBOSE("Returning dynamic symbol with index %u for %s: %p\n", i, symbol.name(), symbol.address().as_ptr());
|
||||||
dbgprintf("Returning dynamic symbol with index %u for %s: %p\n", i, symbol.name(), symbol.address().as_ptr());
|
|
||||||
#endif
|
|
||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,7 +105,12 @@ public:
|
||||||
{
|
{
|
||||||
return m_is_undefined;
|
return m_is_undefined;
|
||||||
}
|
}
|
||||||
VirtualAddress address() const { return m_dynamic.base_address().offset(value()); }
|
VirtualAddress address() const
|
||||||
|
{
|
||||||
|
if (m_dynamic.elf_is_dynamic())
|
||||||
|
return m_dynamic.base_address().offset(value());
|
||||||
|
return VirtualAddress { value() };
|
||||||
|
}
|
||||||
const DynamicObject& object() const { return m_dynamic; }
|
const DynamicObject& object() const { return m_dynamic; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -135,7 +140,10 @@ public:
|
||||||
{
|
{
|
||||||
return !entry_size() ? 0 : size() / entry_size();
|
return !entry_size() ? 0 : size() / entry_size();
|
||||||
}
|
}
|
||||||
VirtualAddress address() const { return m_dynamic.base_address().offset(m_section_offset); }
|
VirtualAddress address() const
|
||||||
|
{
|
||||||
|
return m_dynamic.base_address().offset(m_section_offset);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class RelocationSection;
|
friend class RelocationSection;
|
||||||
|
@ -176,7 +184,12 @@ public:
|
||||||
unsigned type() const { return ELF32_R_TYPE(m_rel.r_info); }
|
unsigned type() const { return ELF32_R_TYPE(m_rel.r_info); }
|
||||||
unsigned symbol_index() const { return ELF32_R_SYM(m_rel.r_info); }
|
unsigned symbol_index() const { return ELF32_R_SYM(m_rel.r_info); }
|
||||||
const Symbol symbol() const { return m_dynamic.symbol(symbol_index()); }
|
const Symbol symbol() const { return m_dynamic.symbol(symbol_index()); }
|
||||||
VirtualAddress address() const { return m_dynamic.base_address().offset(offset()); }
|
VirtualAddress address() const
|
||||||
|
{
|
||||||
|
if (m_dynamic.elf_is_dynamic())
|
||||||
|
return m_dynamic.base_address().offset(offset());
|
||||||
|
return VirtualAddress { offset() };
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const DynamicObject& m_dynamic;
|
const DynamicObject& m_dynamic;
|
||||||
|
@ -274,6 +287,8 @@ public:
|
||||||
using SymbolLookupFunction = DynamicObject::SymbolLookupResult (*)(const char*);
|
using SymbolLookupFunction = DynamicObject::SymbolLookupResult (*)(const char*);
|
||||||
SymbolLookupFunction m_global_symbol_lookup_func { nullptr };
|
SymbolLookupFunction m_global_symbol_lookup_func { nullptr };
|
||||||
|
|
||||||
|
bool elf_is_dynamic() const { return m_is_elf_dynamic; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit DynamicObject(VirtualAddress base_address, VirtualAddress dynamic_section_address);
|
explicit DynamicObject(VirtualAddress base_address, VirtualAddress dynamic_section_address);
|
||||||
|
|
||||||
|
@ -288,6 +303,7 @@ private:
|
||||||
|
|
||||||
VirtualAddress m_base_address;
|
VirtualAddress m_base_address;
|
||||||
VirtualAddress m_dynamic_address;
|
VirtualAddress m_dynamic_address;
|
||||||
|
VirtualAddress m_elf_base_address;
|
||||||
|
|
||||||
unsigned m_symbol_count { 0 };
|
unsigned m_symbol_count { 0 };
|
||||||
|
|
||||||
|
@ -318,6 +334,7 @@ private:
|
||||||
size_t m_size_of_relocation_entry { 0 };
|
size_t m_size_of_relocation_entry { 0 };
|
||||||
size_t m_size_of_relocation_table { 0 };
|
size_t m_size_of_relocation_table { 0 };
|
||||||
FlatPtr m_relocation_table_offset { 0 };
|
FlatPtr m_relocation_table_offset { 0 };
|
||||||
|
bool m_is_elf_dynamic { false };
|
||||||
|
|
||||||
// DT_FLAGS
|
// DT_FLAGS
|
||||||
Elf32_Word m_dt_flags { 0 };
|
Elf32_Word m_dt_flags { 0 };
|
||||||
|
@ -356,7 +373,6 @@ inline void DynamicObject::for_each_dynamic_entry(F func) const
|
||||||
{
|
{
|
||||||
auto* dyns = reinterpret_cast<const Elf32_Dyn*>(m_dynamic_address.as_ptr());
|
auto* dyns = reinterpret_cast<const Elf32_Dyn*>(m_dynamic_address.as_ptr());
|
||||||
for (unsigned i = 0;; ++i) {
|
for (unsigned i = 0;; ++i) {
|
||||||
// dbgprintf("%d\n", i);
|
|
||||||
auto&& dyn = DynamicEntry(dyns[i]);
|
auto&& dyn = DynamicEntry(dyns[i]);
|
||||||
if (dyn.tag() == DT_NULL)
|
if (dyn.tag() == DT_NULL)
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -107,6 +107,7 @@ static void perform_self_relocations(auxv_t* auxvp)
|
||||||
dynamic_object->relocation_section().for_each_relocation([base_address](auto& reloc) {
|
dynamic_object->relocation_section().for_each_relocation([base_address](auto& reloc) {
|
||||||
if (reloc.type() != R_386_RELATIVE)
|
if (reloc.type() != R_386_RELATIVE)
|
||||||
return IterationDecision::Continue;
|
return IterationDecision::Continue;
|
||||||
|
|
||||||
*(u32*)reloc.address().as_ptr() += base_address;
|
*(u32*)reloc.address().as_ptr() += base_address;
|
||||||
return IterationDecision::Continue;
|
return IterationDecision::Continue;
|
||||||
});
|
});
|
||||||
|
@ -171,10 +172,10 @@ static Vector<String> get_dependencies(const String& name)
|
||||||
|
|
||||||
static void map_dependencies(const String& name)
|
static void map_dependencies(const String& name)
|
||||||
{
|
{
|
||||||
VERBOSE("mapping dependencies for: %s", name.characters());
|
VERBOSE("mapping dependencies for: %s\n", name.characters());
|
||||||
|
|
||||||
for (const auto& needed_name : get_dependencies(name)) {
|
for (const auto& needed_name : get_dependencies(name)) {
|
||||||
VERBOSE("needed library: %s", needed_name.characters());
|
VERBOSE("needed library: %s\n", needed_name.characters());
|
||||||
String library_name = get_library_name(needed_name);
|
String library_name = get_library_name(needed_name);
|
||||||
|
|
||||||
if (!g_loaders.contains(library_name)) {
|
if (!g_loaders.contains(library_name)) {
|
||||||
|
@ -193,7 +194,7 @@ static void allocate_tls()
|
||||||
}
|
}
|
||||||
if (total_tls_size) {
|
if (total_tls_size) {
|
||||||
[[maybe_unused]] void* tls_address = allocate_tls(total_tls_size);
|
[[maybe_unused]] void* tls_address = allocate_tls(total_tls_size);
|
||||||
VERBOSE("from userspace, tls_address: %p", tls_address);
|
VERBOSE("from userspace, tls_address: %p\n", tls_address);
|
||||||
}
|
}
|
||||||
g_total_tls_size = total_tls_size;
|
g_total_tls_size = total_tls_size;
|
||||||
}
|
}
|
||||||
|
@ -224,17 +225,17 @@ static void initialize_libc()
|
||||||
|
|
||||||
static void load_elf(const String& name)
|
static void load_elf(const String& name)
|
||||||
{
|
{
|
||||||
VERBOSE("load_elf: %s", name.characters());
|
VERBOSE("load_elf: %s\n", name.characters());
|
||||||
auto loader = g_loaders.get(name).value();
|
auto loader = g_loaders.get(name).value();
|
||||||
|
VERBOSE("a1\n");
|
||||||
for (const auto& needed_name : get_dependencies(name)) {
|
for (const auto& needed_name : get_dependencies(name)) {
|
||||||
VERBOSE("needed library: %s", needed_name.characters());
|
VERBOSE("needed library: %s\n", needed_name.characters());
|
||||||
String library_name = get_library_name(needed_name);
|
String library_name = get_library_name(needed_name);
|
||||||
if (!g_loaded_objects.contains(library_name)) {
|
if (!g_loaded_objects.contains(library_name)) {
|
||||||
load_elf(library_name);
|
load_elf(library_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VERBOSE("loading: %s", name.characters());
|
|
||||||
auto dynamic_object = loader->load_from_image(RTLD_GLOBAL | RTLD_LAZY, g_total_tls_size);
|
auto dynamic_object = loader->load_from_image(RTLD_GLOBAL | RTLD_LAZY, g_total_tls_size);
|
||||||
ASSERT(!dynamic_object.is_null());
|
ASSERT(!dynamic_object.is_null());
|
||||||
g_loaded_objects.set(name, dynamic_object.release_nonnull());
|
g_loaded_objects.set(name, dynamic_object.release_nonnull());
|
||||||
|
@ -270,7 +271,7 @@ static FlatPtr loader_main(auxv_t* auxvp)
|
||||||
|
|
||||||
VERBOSE("loaded all dependencies");
|
VERBOSE("loaded all dependencies");
|
||||||
for ([[maybe_unused]] auto& lib : g_loaders) {
|
for ([[maybe_unused]] auto& lib : g_loaders) {
|
||||||
VERBOSE("%s - tls size: %u, tls offset: %u", lib.key.characters(), lib.value->tls_size(), lib.value->tls_offset());
|
VERBOSE("%s - tls size: %u, tls offset: %u\n", lib.key.characters(), lib.value->tls_size(), lib.value->tls_offset());
|
||||||
}
|
}
|
||||||
|
|
||||||
allocate_tls();
|
allocate_tls();
|
||||||
|
@ -278,8 +279,12 @@ static FlatPtr loader_main(auxv_t* auxvp)
|
||||||
load_elf(main_program_name);
|
load_elf(main_program_name);
|
||||||
|
|
||||||
auto main_program_lib = g_loaders.get(main_program_name).value();
|
auto main_program_lib = g_loaders.get(main_program_name).value();
|
||||||
FlatPtr entry_point = reinterpret_cast<FlatPtr>(main_program_lib->image().entry().as_ptr() + (FlatPtr)main_program_lib->text_segment_load_address().as_ptr());
|
|
||||||
VERBOSE("entry point: %p", entry_point);
|
FlatPtr entry_point = reinterpret_cast<FlatPtr>(main_program_lib->image().entry().as_ptr());
|
||||||
|
if (main_program_lib->is_dynamic())
|
||||||
|
entry_point += reinterpret_cast<FlatPtr>(main_program_lib->text_segment_load_address().as_ptr());
|
||||||
|
|
||||||
|
VERBOSE("entry point: %p\n", entry_point);
|
||||||
|
|
||||||
// This will unmap the temporary memory maps we had for loading the libraries
|
// This will unmap the temporary memory maps we had for loading the libraries
|
||||||
clear_temporary_objects_mappings();
|
clear_temporary_objects_mappings();
|
||||||
|
@ -310,9 +315,9 @@ void _start(int argc, char** argv, char** envp)
|
||||||
}
|
}
|
||||||
|
|
||||||
MainFunction main_function = (MainFunction)(entry);
|
MainFunction main_function = (MainFunction)(entry);
|
||||||
VERBOSE("jumping to main program entry point: %p", main_function);
|
VERBOSE("jumping to main program entry point: %p\n", main_function);
|
||||||
int rc = main_function(argc, argv, envp);
|
int rc = main_function(argc, argv, envp);
|
||||||
VERBOSE("rc: %d", rc);
|
VERBOSE("rc: %d\n", rc);
|
||||||
if (g_libc_exit != nullptr) {
|
if (g_libc_exit != nullptr) {
|
||||||
g_libc_exit(rc);
|
g_libc_exit(rc);
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue