1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-19 07:07:39 +00:00

LibELF+LibC: Support building LibELF for 64-bit targets

This commit is contained in:
Gunnar Beutner 2021-04-30 12:39:56 +02:00 committed by Andreas Kling
parent e468bf08b1
commit fdbe66a7b4
3 changed files with 45 additions and 39 deletions

View file

@ -11,17 +11,22 @@
#else #else
# include <elf.h> # include <elf.h>
#endif #endif
#include <limits.h>
#include <sys/cdefs.h> #include <sys/cdefs.h>
__BEGIN_DECLS __BEGIN_DECLS
#define ElfW(type) Elf32_##type #ifdef __LP64__
# define ElfW(type) Elf64_##type
#else
# define ElfW(type) Elf32_##type
#endif
struct dl_phdr_info { struct dl_phdr_info {
Elf32_Addr dlpi_addr; ElfW(Addr) dlpi_addr;
const char* dlpi_name; const char* dlpi_name;
const Elf32_Phdr* dlpi_phdr; const ElfW(Phdr) * dlpi_phdr;
Elf32_Half dlpi_phnum; ElfW(Half) dlpi_phnum;
}; };
int dl_iterate_phdr(int (*callback)(struct dl_phdr_info* info, size_t size, void* data), void* data); int dl_iterate_phdr(int (*callback)(struct dl_phdr_info* info, size_t size, void* data), void* data);

View file

@ -16,15 +16,15 @@
namespace ELF { namespace ELF {
static const char* name_for_dtag(Elf32_Sword d_tag); static const char* name_for_dtag(ElfW(Sword) d_tag);
DynamicObject::DynamicObject(const String& filename, VirtualAddress base_address, VirtualAddress dynamic_section_address) DynamicObject::DynamicObject(const String& filename, VirtualAddress base_address, VirtualAddress dynamic_section_address)
: m_filename(filename) : m_filename(filename)
, m_base_address(base_address) , m_base_address(base_address)
, m_dynamic_address(dynamic_section_address) , m_dynamic_address(dynamic_section_address)
{ {
auto* header = (Elf32_Ehdr*)base_address.as_ptr(); auto* header = (ElfW(Ehdr)*)base_address.as_ptr();
auto* pheader = (Elf32_Phdr*)(base_address.as_ptr() + header->e_phoff); auto* pheader = (ElfW(Phdr)*)(base_address.as_ptr() + header->e_phoff);
m_elf_base_address = VirtualAddress(pheader->p_vaddr - pheader->p_offset); m_elf_base_address = VirtualAddress(pheader->p_vaddr - pheader->p_offset);
if (header->e_type == ET_DYN) if (header->e_type == ET_DYN)
m_is_elf_dynamic = true; m_is_elf_dynamic = true;
@ -178,7 +178,7 @@ void DynamicObject::parse()
// TODO: FIXME, this shouldn't be hardcoded // TODO: FIXME, this shouldn't be hardcoded
// The reason we need this here is that 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(ElfW(Rel));
} }
auto hash_section_address = hash_section().address().as_ptr(); auto hash_section_address = hash_section().address().as_ptr();
@ -191,21 +191,21 @@ DynamicObject::Relocation DynamicObject::RelocationSection::relocation(unsigned
{ {
VERIFY(index < entry_count()); VERIFY(index < entry_count());
unsigned offset_in_section = index * entry_size(); unsigned offset_in_section = index * entry_size();
auto relocation_address = (Elf32_Rel*)address().offset(offset_in_section).as_ptr(); auto relocation_address = (ElfW(Rel)*)address().offset(offset_in_section).as_ptr();
return Relocation(m_dynamic, *relocation_address, offset_in_section); return Relocation(m_dynamic, *relocation_address, offset_in_section);
} }
DynamicObject::Relocation DynamicObject::RelocationSection::relocation_at_offset(unsigned offset) const DynamicObject::Relocation DynamicObject::RelocationSection::relocation_at_offset(unsigned offset) const
{ {
VERIFY(offset <= (m_section_size_bytes - m_entry_size)); VERIFY(offset <= (m_section_size_bytes - m_entry_size));
auto relocation_address = (Elf32_Rel*)address().offset(offset).as_ptr(); auto relocation_address = (ElfW(Rel)*)address().offset(offset).as_ptr();
return Relocation(m_dynamic, *relocation_address, offset); return Relocation(m_dynamic, *relocation_address, offset);
} }
DynamicObject::Symbol DynamicObject::symbol(unsigned index) 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_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(); auto symbol_entry = (ElfW(Sym)*)symbol_section.address().offset(index * symbol_section.entry_size()).as_ptr();
return Symbol(*this, index, *symbol_entry); return Symbol(*this, index, *symbol_entry);
} }
@ -239,16 +239,16 @@ 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"sv)); return RelocationSection(Section(*this, m_plt_relocation_offset_location, m_size_of_plt_relocation_entry_list, m_size_of_relocation_entry, "DT_JMPREL"sv));
} }
Elf32_Half DynamicObject::program_header_count() const ElfW(Half) DynamicObject::program_header_count() const
{ {
auto* header = (const Elf32_Ehdr*)m_base_address.as_ptr(); auto* header = (const ElfW(Ehdr)*)m_base_address.as_ptr();
return header->e_phnum; return header->e_phnum;
} }
const Elf32_Phdr* DynamicObject::program_headers() const const ElfW(Phdr) * DynamicObject::program_headers() const
{ {
auto* header = (const Elf32_Ehdr*)m_base_address.as_ptr(); auto* header = (const ElfW(Ehdr)*)m_base_address.as_ptr();
return (const Elf32_Phdr*)(m_base_address.as_ptr() + header->e_phoff); return (const ElfW(Phdr)*)(m_base_address.as_ptr() + header->e_phoff);
} }
auto DynamicObject::HashSection::lookup_sysv_symbol(const StringView& name, u32 hash_value) const -> Optional<Symbol> auto DynamicObject::HashSection::lookup_sysv_symbol(const StringView& name, u32 hash_value) const -> Optional<Symbol>
@ -319,12 +319,12 @@ auto DynamicObject::HashSection::lookup_gnu_symbol(const StringView& name, u32 h
return {}; return {};
} }
StringView DynamicObject::symbol_string_table_string(Elf32_Word index) const StringView DynamicObject::symbol_string_table_string(ElfW(Word) index) const
{ {
return StringView { (const char*)base_address().offset(m_string_table_offset + index).as_ptr() }; return StringView { (const char*)base_address().offset(m_string_table_offset + index).as_ptr() };
} }
const char* DynamicObject::raw_symbol_string_table_string(Elf32_Word index) const const char* DynamicObject::raw_symbol_string_table_string(ElfW(Word) index) const
{ {
return (const char*)base_address().offset(m_string_table_offset + index).as_ptr(); return (const char*)base_address().offset(m_string_table_offset + index).as_ptr();
} }
@ -335,7 +335,7 @@ DynamicObject::InitializationFunction DynamicObject::init_section_function() con
return (InitializationFunction)init_section().address().as_ptr(); return (InitializationFunction)init_section().address().as_ptr();
} }
static const char* name_for_dtag(Elf32_Sword d_tag) static const char* name_for_dtag(ElfW(Sword) d_tag)
{ {
switch (d_tag) { switch (d_tag) {
case DT_NULL: case DT_NULL:

View file

@ -12,6 +12,7 @@
#include <AK/String.h> #include <AK/String.h>
#include <Kernel/VirtualAddress.h> #include <Kernel/VirtualAddress.h>
#include <LibC/elf.h> #include <LibC/elf.h>
#include <LibC/link.h>
namespace ELF { namespace ELF {
@ -31,24 +32,24 @@ public:
class DynamicEntry { class DynamicEntry {
public: public:
explicit DynamicEntry(const Elf32_Dyn& dyn) explicit DynamicEntry(const ElfW(Dyn) & dyn)
: m_dyn(dyn) : m_dyn(dyn)
{ {
} }
~DynamicEntry() { } ~DynamicEntry() { }
Elf32_Sword tag() const { return m_dyn.d_tag; } ElfW(Sword) tag() const { return m_dyn.d_tag; }
Elf32_Addr ptr() const { return m_dyn.d_un.d_ptr; } ElfW(Addr) ptr() const { return m_dyn.d_un.d_ptr; }
Elf32_Word val() const { return m_dyn.d_un.d_val; } ElfW(Word) val() const { return m_dyn.d_un.d_val; }
private: private:
const Elf32_Dyn& m_dyn; const ElfW(Dyn) & m_dyn;
}; };
class Symbol { class Symbol {
public: public:
Symbol(const DynamicObject& dynamic, unsigned index, const Elf32_Sym& sym) Symbol(const DynamicObject& dynamic, unsigned index, const ElfW(Sym) & sym)
: m_dynamic(dynamic) : m_dynamic(dynamic)
, m_sym(sym) , m_sym(sym)
, m_index(index) , m_index(index)
@ -76,7 +77,7 @@ public:
private: private:
const DynamicObject& m_dynamic; const DynamicObject& m_dynamic;
const Elf32_Sym& m_sym; const ElfW(Sym) & m_sym;
const unsigned m_index; const unsigned m_index;
}; };
@ -130,7 +131,7 @@ public:
class Relocation { class Relocation {
public: public:
Relocation(const DynamicObject& dynamic, const Elf32_Rel& rel, unsigned offset_in_section) Relocation(const DynamicObject& dynamic, const ElfW(Rel) & rel, unsigned offset_in_section)
: m_dynamic(dynamic) : m_dynamic(dynamic)
, m_rel(rel) , m_rel(rel)
, m_offset_in_section(offset_in_section) , m_offset_in_section(offset_in_section)
@ -153,7 +154,7 @@ public:
private: private:
const DynamicObject& m_dynamic; const DynamicObject& m_dynamic;
const Elf32_Rel& m_rel; const ElfW(Rel) & m_rel;
const unsigned m_offset_in_section; const unsigned m_offset_in_section;
}; };
@ -247,8 +248,8 @@ public:
void set_tls_offset(FlatPtr offset) { m_tls_offset = offset; } void set_tls_offset(FlatPtr offset) { m_tls_offset = offset; }
void set_tls_size(FlatPtr size) { m_tls_size = size; } void set_tls_size(FlatPtr size) { m_tls_size = size; }
Elf32_Half program_header_count() const; ElfW(Half) program_header_count() const;
const Elf32_Phdr* program_headers() const; const ElfW(Phdr) * program_headers() const;
template<typename F> template<typename F>
void for_each_needed_library(F) const; void for_each_needed_library(F) const;
@ -283,8 +284,8 @@ public:
private: private:
explicit DynamicObject(const String& filename, VirtualAddress base_address, VirtualAddress dynamic_section_address); explicit DynamicObject(const String& filename, VirtualAddress base_address, VirtualAddress dynamic_section_address);
StringView symbol_string_table_string(Elf32_Word) const; StringView symbol_string_table_string(ElfW(Word)) const;
const char* raw_symbol_string_table_string(Elf32_Word) const; const char* raw_symbol_string_table_string(ElfW(Word)) const;
void parse(); void parse();
String m_filename; String m_filename;
@ -312,7 +313,7 @@ private:
FlatPtr m_symbol_table_offset { 0 }; FlatPtr m_symbol_table_offset { 0 };
size_t m_size_of_symbol_table_entry { 0 }; size_t m_size_of_symbol_table_entry { 0 };
Elf32_Sword m_procedure_linkage_table_relocation_type { -1 }; ElfW(Sword) m_procedure_linkage_table_relocation_type { -1 };
FlatPtr m_plt_relocation_offset_location { 0 }; // offset of PLT relocations, at end of relocations FlatPtr m_plt_relocation_offset_location { 0 }; // offset of PLT relocations, at end of relocations
size_t m_size_of_plt_relocation_entry_list { 0 }; size_t m_size_of_plt_relocation_entry_list { 0 };
Optional<FlatPtr> m_procedure_linkage_table_offset; Optional<FlatPtr> m_procedure_linkage_table_offset;
@ -326,14 +327,14 @@ private:
bool m_is_elf_dynamic { false }; bool m_is_elf_dynamic { false };
// DT_FLAGS // DT_FLAGS
Elf32_Word m_dt_flags { 0 }; ElfW(Word) m_dt_flags { 0 };
bool m_has_soname { false }; bool m_has_soname { false };
Elf32_Word m_soname_index { 0 }; // Index into dynstr table for SONAME ElfW(Word) m_soname_index { 0 }; // Index into dynstr table for SONAME
bool m_has_rpath { false }; bool m_has_rpath { false };
Elf32_Word m_rpath_index { 0 }; // Index into dynstr table for RPATH ElfW(Word) m_rpath_index { 0 }; // Index into dynstr table for RPATH
bool m_has_runpath { false }; bool m_has_runpath { false };
Elf32_Word m_runpath_index { 0 }; // Index into dynstr table for RUNPATH ElfW(Word) m_runpath_index { 0 }; // Index into dynstr table for RUNPATH
Optional<FlatPtr> m_tls_offset; Optional<FlatPtr> m_tls_offset;
Optional<FlatPtr> m_tls_size; Optional<FlatPtr> m_tls_size;
@ -364,7 +365,7 @@ inline void DynamicObject::for_each_symbol(F func) const
template<typename F> template<typename F>
inline void DynamicObject::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()); auto* dyns = reinterpret_cast<const ElfW(Dyn)*>(m_dynamic_address.as_ptr());
for (unsigned i = 0;; ++i) { for (unsigned i = 0;; ++i) {
auto&& dyn = DynamicEntry(dyns[i]); auto&& dyn = DynamicEntry(dyns[i]);
if (dyn.tag() == DT_NULL) if (dyn.tag() == DT_NULL)
@ -379,7 +380,7 @@ inline void DynamicObject::for_each_needed_library(F func) const
for_each_dynamic_entry([func, this](auto entry) { for_each_dynamic_entry([func, this](auto entry) {
if (entry.tag() != DT_NEEDED) if (entry.tag() != DT_NEEDED)
return IterationDecision::Continue; return IterationDecision::Continue;
Elf32_Word offset = entry.val(); ElfW(Word) offset = entry.val();
StringView name { (const char*)(m_base_address.offset(m_string_table_offset).offset(offset)).as_ptr() }; StringView name { (const char*)(m_base_address.offset(m_string_table_offset).offset(offset)).as_ptr() };
if (func(StringView(name)) == IterationDecision::Break) if (func(StringView(name)) == IterationDecision::Break)
return IterationDecision::Break; return IterationDecision::Break;