1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 13:17:35 +00:00

LibELF: Store DynamicLoader ELF images using an OwnPtr

This is preparation work for the next commit, where we will replace the
stored ELF image mid-load.
This commit is contained in:
Tim Schumacher 2022-06-04 23:29:09 +02:00 committed by Linus Groh
parent 07208feae7
commit c1d8612eb5
2 changed files with 16 additions and 16 deletions

View file

@ -67,8 +67,8 @@ DynamicLoader::DynamicLoader(int fd, String filename, void* data, size_t size, S
, m_file_size(size) , m_file_size(size)
, m_image_fd(fd) , m_image_fd(fd)
, m_file_data(data) , m_file_data(data)
, m_elf_image((u8*)m_file_data, m_file_size)
{ {
m_elf_image = adopt_own(*new ELF::Image((u8*)m_file_data, m_file_size));
m_valid = validate(); m_valid = validate();
if (m_valid) if (m_valid)
m_tls_size_of_current_object = calculate_tls_size(); m_tls_size_of_current_object = calculate_tls_size();
@ -93,14 +93,14 @@ DynamicObject const& DynamicLoader::dynamic_object() const
if (!m_cached_dynamic_object) { if (!m_cached_dynamic_object) {
VirtualAddress dynamic_section_address; VirtualAddress dynamic_section_address;
m_elf_image.for_each_program_header([&dynamic_section_address](auto program_header) { image().for_each_program_header([&dynamic_section_address](auto program_header) {
if (program_header.type() == PT_DYNAMIC) { if (program_header.type() == PT_DYNAMIC) {
dynamic_section_address = VirtualAddress(program_header.raw_data()); dynamic_section_address = VirtualAddress(program_header.raw_data());
} }
}); });
VERIFY(!dynamic_section_address.is_null()); VERIFY(!dynamic_section_address.is_null());
m_cached_dynamic_object = ELF::DynamicObject::create(m_filename, VirtualAddress(m_elf_image.base_address()), dynamic_section_address); m_cached_dynamic_object = ELF::DynamicObject::create(m_filename, VirtualAddress(image().base_address()), dynamic_section_address);
} }
return *m_cached_dynamic_object; return *m_cached_dynamic_object;
} }
@ -108,7 +108,7 @@ DynamicObject const& DynamicLoader::dynamic_object() const
size_t DynamicLoader::calculate_tls_size() const size_t DynamicLoader::calculate_tls_size() const
{ {
size_t tls_size = 0; size_t tls_size = 0;
m_elf_image.for_each_program_header([&tls_size](auto program_header) { image().for_each_program_header([&tls_size](auto program_header) {
if (program_header.type() == PT_TLS) { if (program_header.type() == PT_TLS) {
tls_size = program_header.size_in_memory(); tls_size = program_header.size_in_memory();
} }
@ -118,7 +118,7 @@ size_t DynamicLoader::calculate_tls_size() const
bool DynamicLoader::validate() bool DynamicLoader::validate()
{ {
if (!m_elf_image.is_valid()) if (!image().is_valid())
return false; return false;
auto* elf_header = (ElfW(Ehdr)*)m_file_data; auto* elf_header = (ElfW(Ehdr)*)m_file_data;
@ -271,7 +271,7 @@ void DynamicLoader::load_program_headers()
VirtualAddress dynamic_region_desired_vaddr; VirtualAddress dynamic_region_desired_vaddr;
m_elf_image.for_each_program_header([&](Image::ProgramHeader const& program_header) { image().for_each_program_header([&](Image::ProgramHeader const& program_header) {
ProgramHeaderRegion region {}; ProgramHeaderRegion region {};
region.set_program_header(program_header.raw_header()); region.set_program_header(program_header.raw_header());
if (region.is_tls_template()) { if (region.is_tls_template()) {
@ -305,10 +305,10 @@ void DynamicLoader::load_program_headers()
quick_sort(copy_regions, compare_load_address); quick_sort(copy_regions, compare_load_address);
// Process regions in order: .text, .data, .tls // Process regions in order: .text, .data, .tls
void* requested_load_address = m_elf_image.is_dynamic() ? nullptr : load_regions.first().desired_load_address().as_ptr(); void* requested_load_address = image().is_dynamic() ? nullptr : load_regions.first().desired_load_address().as_ptr();
int reservation_mmap_flags = MAP_ANON | MAP_PRIVATE | MAP_NORESERVE; int reservation_mmap_flags = MAP_ANON | MAP_PRIVATE | MAP_NORESERVE;
if (m_elf_image.is_dynamic()) if (image().is_dynamic())
reservation_mmap_flags |= MAP_RANDOMIZED; reservation_mmap_flags |= MAP_RANDOMIZED;
#ifdef MAP_FIXED_NOREPLACE #ifdef MAP_FIXED_NOREPLACE
else else
@ -377,7 +377,7 @@ void DynamicLoader::load_program_headers()
m_relro_segment_address = VirtualAddress { (u8*)reservation + relro_region->desired_load_address().get() - ph_load_base }; m_relro_segment_address = VirtualAddress { (u8*)reservation + relro_region->desired_load_address().get() - ph_load_base };
} }
if (m_elf_image.is_dynamic()) if (image().is_dynamic())
m_dynamic_section_address = VirtualAddress { (u8*)reservation + dynamic_region_desired_vaddr.get() - ph_load_base }; m_dynamic_section_address = VirtualAddress { (u8*)reservation + dynamic_region_desired_vaddr.get() - ph_load_base };
else else
m_dynamic_section_address = dynamic_region_desired_vaddr; m_dynamic_section_address = dynamic_region_desired_vaddr;
@ -405,7 +405,7 @@ void DynamicLoader::load_program_headers()
} }
VirtualAddress data_segment_start; VirtualAddress data_segment_start;
if (m_elf_image.is_dynamic()) if (image().is_dynamic())
data_segment_start = VirtualAddress { (u8*)reservation + region.desired_load_address().get() }; data_segment_start = VirtualAddress { (u8*)reservation + region.desired_load_address().get() };
else else
data_segment_start = region.desired_load_address(); data_segment_start = region.desired_load_address();
@ -554,7 +554,7 @@ DynamicLoader::RelocationResult DynamicLoader::do_relocation(const ELF::DynamicO
} else { } else {
auto relocation_address = (FlatPtr*)relocation.address().as_ptr(); auto relocation_address = (FlatPtr*)relocation.address().as_ptr();
if (m_elf_image.is_dynamic()) if (image().is_dynamic())
*relocation_address += m_dynamic_object->base_address().get(); *relocation_address += m_dynamic_object->base_address().get();
} }
break; break;
@ -607,7 +607,7 @@ void DynamicLoader::copy_initial_tls_data_into(ByteBuffer& buffer) const
u8 const* tls_data = nullptr; u8 const* tls_data = nullptr;
size_t tls_size_in_image = 0; size_t tls_size_in_image = 0;
m_elf_image.for_each_program_header([this, &tls_data, &tls_size_in_image](ELF::Image::ProgramHeader program_header) { image().for_each_program_header([this, &tls_data, &tls_size_in_image](ELF::Image::ProgramHeader program_header) {
if (program_header.type() != PT_TLS) if (program_header.type() != PT_TLS)
return IterationDecision::Continue; return IterationDecision::Continue;
@ -619,7 +619,7 @@ void DynamicLoader::copy_initial_tls_data_into(ByteBuffer& buffer) const
if (!tls_data || !tls_size_in_image) if (!tls_data || !tls_size_in_image)
return; return;
m_elf_image.for_each_symbol([this, &buffer, tls_data](ELF::Image::Symbol symbol) { image().for_each_symbol([this, &buffer, tls_data](ELF::Image::Symbol symbol) {
if (symbol.type() != STT_TLS) if (symbol.type() != STT_TLS)
return IterationDecision::Continue; return IterationDecision::Continue;

View file

@ -68,14 +68,14 @@ public:
void set_tls_offset(size_t offset) { m_tls_offset = offset; }; void set_tls_offset(size_t offset) { m_tls_offset = offset; };
size_t tls_size_of_current_object() const { return m_tls_size_of_current_object; } size_t tls_size_of_current_object() const { return m_tls_size_of_current_object; }
size_t tls_offset() const { return m_tls_offset; } size_t tls_offset() const { return m_tls_offset; }
const ELF::Image& image() const { return m_elf_image; } const ELF::Image& image() const { return *m_elf_image; }
template<typename F> template<typename F>
void for_each_needed_library(F) const; void for_each_needed_library(F) const;
VirtualAddress base_address() const { return m_base_address; } VirtualAddress base_address() const { return m_base_address; }
Vector<LoadedSegment> const text_segments() const { return m_text_segments; } Vector<LoadedSegment> const text_segments() const { return m_text_segments; }
bool is_dynamic() const { return m_elf_image.is_dynamic(); } bool is_dynamic() const { return image().is_dynamic(); }
static Optional<DynamicObject::SymbolLookupResult> lookup_symbol(const ELF::DynamicObject::Symbol&); static Optional<DynamicObject::SymbolLookupResult> lookup_symbol(const ELF::DynamicObject::Symbol&);
void copy_initial_tls_data_into(ByteBuffer& buffer) const; void copy_initial_tls_data_into(ByteBuffer& buffer) const;
@ -139,7 +139,7 @@ private:
size_t m_file_size { 0 }; size_t m_file_size { 0 };
int m_image_fd { -1 }; int m_image_fd { -1 };
void* m_file_data { nullptr }; void* m_file_data { nullptr };
ELF::Image m_elf_image; OwnPtr<ELF::Image> m_elf_image;
bool m_valid { true }; bool m_valid { true };
RefPtr<DynamicObject> m_dynamic_object; RefPtr<DynamicObject> m_dynamic_object;