1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 23:37:36 +00:00

LibELF: Only call IFUNC resolvers after populating the PLT

As IFUNC resolvers may call arbitrary functions though the PLT, they can
only be called after the PLT has been populated. This is true of the
`[[gnu::target_clones]]` attribute, which makes a call to
`__cpu_indicator_init`, which is defined in `libgcc_s.so`, through the
PLT.

`do_plt_relocation` and `do_direct_relocation` are given a parameter
that controls whether IFUNCs are immediately resolved. In the first
pass, relocations pointing to IFUNCs are put on a worklist, while all
other relocations are performed. Only after non-IFUNC relocations are
done and the PLT is set up do we deal with these.
This commit is contained in:
Daniel Bertalan 2023-04-22 12:09:00 +02:00 committed by Andreas Kling
parent cd45c2d295
commit e2b1f9447c
2 changed files with 53 additions and 15 deletions

View file

@ -40,6 +40,11 @@ enum class ShouldInitializeWeak {
No
};
enum class ShouldCallIfuncResolver {
Yes,
No
};
extern "C" FlatPtr _fixup_plt_entry(DynamicObject* object, u32 relocation_offset);
class DynamicLoader : public RefCounted<DynamicLoader> {
@ -115,8 +120,6 @@ private:
ElfW(Phdr) m_program_header; // Explicitly a copy of the PHDR in the image
};
friend FlatPtr _fixup_plt_entry(DynamicObject*, u32);
// Stage 1
void load_program_headers();
@ -132,13 +135,17 @@ private:
bool validate();
friend FlatPtr _fixup_plt_entry(DynamicObject*, u32);
enum class RelocationResult : uint8_t {
Failed = 0,
Success = 1,
ResolveLater = 2,
CallIfuncResolver = 3,
};
RelocationResult do_direct_relocation(DynamicObject::Relocation const&, ShouldInitializeWeak);
static RelocationResult do_plt_relocation(DynamicObject::Relocation const&);
RelocationResult do_direct_relocation(DynamicObject::Relocation const&, ShouldInitializeWeak, ShouldCallIfuncResolver);
// Will be called from _fixup_plt_entry, as part of the PLT trampoline
static RelocationResult do_plt_relocation(DynamicObject::Relocation const&, ShouldCallIfuncResolver);
void do_relr_relocations();
void find_tls_size_and_alignment();
@ -164,6 +171,8 @@ private:
size_t m_tls_alignment_of_current_object { 0 };
Vector<DynamicObject::Relocation> m_unresolved_relocations;
Vector<DynamicObject::Relocation> m_direct_ifunc_relocations;
Vector<DynamicObject::Relocation> m_plt_ifunc_relocations;
mutable RefPtr<DynamicObject> m_cached_dynamic_object;