1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-18 15:15:08 +00:00

LibELF: Add ELFDynamicObject to dynamically load libaries

This patch also adds some missing relocation defines to exec_elf.h,
and a few helper classes/methods to ELFImage so that we can use it
for our dynamically loaded libs and not just main program images from
the kernel :)
This commit is contained in:
Andrew Kaster 2019-12-31 16:45:50 -05:00 committed by Andreas Kling
parent b6590b7f83
commit a18b37880e
5 changed files with 941 additions and 5 deletions

View file

@ -43,6 +43,11 @@ unsigned ELFImage::symbol_count() const
return section(m_symbol_table_section_index).entry_count();
}
unsigned ELFImage::dynamic_symbol_count() const
{
return section(m_dynamic_symbol_table_section_index).entry_count();
}
void ELFImage::dump() const
{
dbgprintf("ELFImage{%p} {\n", this);
@ -110,8 +115,25 @@ bool ELFImage::parse()
m_symbol_table_section_index = i;
}
if (sh.sh_type == SHT_STRTAB && i != header().e_shstrndx) {
ASSERT(!m_string_table_section_index || m_string_table_section_index == i);
m_string_table_section_index = i;
if (StringView(".strtab") == section_header_table_string(sh.sh_name))
m_string_table_section_index = i;
else if (StringView(".dynstr") == section_header_table_string(sh.sh_name))
m_dynamic_string_table_section_index = i;
else
ASSERT_NOT_REACHED();
}
if (sh.sh_type == SHT_DYNAMIC) {
ASSERT(!m_dynamic_section_index || m_dynamic_section_index == i);
m_dynamic_section_index = i;
}
if (sh.sh_type == SHT_DYNSYM) {
ASSERT(!m_dynamic_symbol_table_section_index || m_dynamic_symbol_table_section_index == i);
m_dynamic_symbol_table_section_index = i;
}
if (sh.sh_type == SHT_REL) {
if (StringView(".rel.dyn") == section_header_table_string(sh.sh_name)) {
m_dynamic_relocation_section_index = i;
}
}
}
@ -140,6 +162,14 @@ const char* ELFImage::table_string(unsigned offset) const
return raw_data(sh.sh_offset + offset);
}
const char* ELFImage::dynamic_table_string(unsigned offset) const
{
auto& sh = section_header(m_dynamic_string_table_section_index);
if (sh.sh_type != SHT_STRTAB)
return nullptr;
return raw_data(sh.sh_offset + offset);
}
const char* ELFImage::raw_data(unsigned offset) const
{
return reinterpret_cast<const char*>(m_buffer) + offset;
@ -159,7 +189,7 @@ const Elf32_Phdr& ELFImage::program_header_internal(unsigned index) const
const Elf32_Shdr& ELFImage::section_header(unsigned index) const
{
ASSERT(index < header().e_shnum);
return *reinterpret_cast<const Elf32_Shdr*>(raw_data(header().e_shoff + (index * sizeof(Elf32_Shdr))));
return *reinterpret_cast<const Elf32_Shdr*>(raw_data(header().e_shoff + (index * header().e_shentsize)));
}
const ELFImage::Symbol ELFImage::symbol(unsigned index) const
@ -169,6 +199,13 @@ const ELFImage::Symbol ELFImage::symbol(unsigned index) const
return Symbol(*this, index, raw_syms[index]);
}
const ELFImage::DynamicSymbol ELFImage::dynamic_symbol(unsigned index) const
{
ASSERT(index < symbol_count());
auto* raw_syms = reinterpret_cast<const Elf32_Sym*>(raw_data(section(m_dynamic_symbol_table_section_index).offset()));
return DynamicSymbol(*this, index, raw_syms[index]);
}
const ELFImage::Section ELFImage::section(unsigned index) const
{
ASSERT(index < section_count());
@ -188,6 +225,13 @@ const ELFImage::Relocation ELFImage::RelocationSection::relocation(unsigned inde
return Relocation(m_image, rels[index]);
}
const ELFImage::DynamicRelocation ELFImage::DynamicRelocationSection::relocation(unsigned index) const
{
ASSERT(index < relocation_count());
auto* rels = reinterpret_cast<const Elf32_Rel*>(m_image.raw_data(offset()));
return DynamicRelocation(m_image, rels[index]);
}
const ELFImage::RelocationSection ELFImage::Section::relocations() const
{
// FIXME: This is ugly.
@ -213,3 +257,15 @@ const ELFImage::Section ELFImage::lookup_section(const char* name) const
return section((*it).value);
return section(0);
}
const ELFImage::DynamicSection ELFImage::dynamic_section() const
{
ASSERT(is_dynamic());
return section(m_dynamic_section_index);
}
const ELFImage::DynamicRelocationSection ELFImage::dynamic_relocation_section() const
{
ASSERT(is_dynamic());
return section(m_dynamic_relocation_section_index);
}