Repository: SerenityOS/serenity
File: Userland/Libraries/LibELF/DynamicLoader.cpp (C++)

Code before:
    got_ptr[1] = (FlatPtr)m_dynamic_object.ptr();
#else
#    error Unknown architecture
#endif
}

// Called from our ASM routine _plt_trampoline.
extern "C" FlatPtr _fixup_plt_entry(DynamicObject* object, u32 relocation_offset)
{
    auto const& relocation = object->plt_relocation_section().relocation_at_offset(relocation_offset);
    auto result = DynamicLoader::do_plt_relocation(relocation, ShouldCallIfuncResolver::Yes);
    if (result != DynamicLoader::RelocationResult::Success) {
        dbgln("Loader.so: {} unresolved symbol '{}'", object->filepath(), relocation.symbol().name());
        VERIFY_NOT_REACHED();
    }
    return *reinterpret_cast<FlatPtr*>(relocation.address().as_ptr());
}

void DynamicLoader::call_object_init_functions()
{
    typedef void (*InitFunc)();

    if (m_dynamic_object->has_init_section()) {
        dbgln("DynamicLoader: Object has obsolete init_section {}", filepath());
        VERIFY_NOT_REACHED();
    }

    if (m_dynamic_object->has_init_array_section()) {
        auto init_array_section = m_dynamic_object->init_array_section();

        InitFunc* init_begin = (InitFunc*)(init_array_section.address().as_ptr());
        InitFunc* init_end = init_begin + init_array_section.entry_count();
        while (init_begin != init_end) {
            // Android sources claim that these can be -1, to be ignored.
            // 0 definitely shows up. Apparently 0/-1 are valid? Confusing.
            if (!*init_begin || ((FlatPtr)*init_begin == (FlatPtr)-1))
                continue;
            (*init_begin)();
            ++init_begin;
        }
    }
}

Optional<DynamicObject::SymbolLookupResult> DynamicLoader::lookup_symbol(const ELF::DynamicObject::Symbol& symbol)
{
    if (symbol.is_undefined() || symbol.bind() == STB_WEAK)
        return DynamicLinker::lookup_global_symbol(symbol.name());

    return DynamicObject::SymbolLookupResult { symbol.value(), symbol.size(), symbol.address(), symbol.bind(), symbol.type(), &symbol.object() };
}


Review comment (suggestion):
I would also check for DT_FINI somewhere. We currently call it here on exit: https://github.com/SerenityOS/serenity/blob/350fc077120fa4689c6f377f1d7c6f0afa0a4e56/Userland/Libraries/LibELF/DynamicLinker.cpp#L614-L617

Since we don't need the actual DT_INIT/DT_FINI address, we could maybe remove all associated functions/variables and throw the errors here?:
https://github.com/SerenityOS/serenity/blob/350fc077120fa4689c6f377f1d7c6f0afa0a4e56/Userland/Libraries/LibELF/DynamicObject.cpp#L82-L87

Code after:
    got_ptr[1] = (FlatPtr)m_dynamic_object.ptr();
#else
#    error Unknown architecture
#endif
}

// Called from our ASM routine _plt_trampoline.
extern "C" FlatPtr _fixup_plt_entry(DynamicObject* object, u32 relocation_offset)
{
    auto const& relocation = object->plt_relocation_section().relocation_at_offset(relocation_offset);
    auto result = DynamicLoader::do_plt_relocation(relocation, ShouldCallIfuncResolver::Yes);
    if (result != DynamicLoader::RelocationResult::Success) {
        dbgln("Loader.so: {} unresolved symbol '{}'", object->filepath(), relocation.symbol().name());
        VERIFY_NOT_REACHED();
    }
    return *reinterpret_cast<FlatPtr*>(relocation.address().as_ptr());
}

void DynamicLoader::call_object_init_functions()
{
    typedef void (*InitFunc)();

    if (m_dynamic_object->has_init_array_section()) {
        auto init_array_section = m_dynamic_object->init_array_section();

        InitFunc* init_begin = (InitFunc*)(init_array_section.address().as_ptr());
        InitFunc* init_end = init_begin + init_array_section.entry_count();
        while (init_begin != init_end) {
            // Android sources claim that these can be -1, to be ignored.
            // 0 definitely shows up. Apparently 0/-1 are valid? Confusing.
            if (!*init_begin || ((FlatPtr)*init_begin == (FlatPtr)-1))
                continue;
            (*init_begin)();
            ++init_begin;
        }
    }
}

Optional<DynamicObject::SymbolLookupResult> DynamicLoader::lookup_symbol(const ELF::DynamicObject::Symbol& symbol)
{
    if (symbol.is_undefined() || symbol.bind() == STB_WEAK)
        return DynamicLinker::lookup_global_symbol(symbol.name());

    return DynamicObject::SymbolLookupResult { symbol.value(), symbol.size(), symbol.address(), symbol.bind(), symbol.type(), &symbol.object() };
}

void DynamicLoader::compute_topological_order(Vector<NonnullRefPtr<DynamicLoader>>& topological_order)
{
    VERIFY(m_topological_ordering_state == TopologicalOrderingState::NotVisited);
    m_topological_ordering_state = TopologicalOrderingState::Visiting;