summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibDebug/ProcessInspector.cpp
blob: bf07ff3dab5fb98bacd3b16fa7f9849de3d9fdc8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/*
 * Copyright (c) 2021, Itamar S. <itamar8910@gmail.com>
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#include "ProcessInspector.h"
#include "DebugInfo.h"

namespace Debug {

LoadedLibrary const* ProcessInspector::library_at(FlatPtr address) const
{
    LoadedLibrary const* result = nullptr;
    for_each_loaded_library([&result, address](auto const& lib) {
        if (address >= lib.base_address && address < lib.base_address + lib.debug_info->elf().size()) {
            result = &lib;
            return IterationDecision::Break;
        }
        return IterationDecision::Continue;
    });
    return result;
}

Optional<ProcessInspector::SymbolicationResult> ProcessInspector::symbolicate(FlatPtr address) const
{
    auto* lib = library_at(address);
    if (!lib)
        return {};
    // FIXME: ELF::Image symbolicate() API should return String::empty() if symbol is not found (It currently returns ??)
    auto symbol = lib->debug_info->elf().symbolicate(address - lib->base_address);
    return { { lib->name, symbol } };
}

Optional<DebugInfo::SourcePositionAndAddress> ProcessInspector::get_address_from_source_position(String const& file, size_t line) const
{
    Optional<DebugInfo::SourcePositionAndAddress> result;
    for_each_loaded_library([file, line, &result](auto& lib) {
        // The loader contains its own definitions for LibC symbols, so we don't want to include it in the search.
        if (lib.name == "Loader.so")
            return IterationDecision::Continue;

        auto source_position_and_address = lib.debug_info->get_address_from_source_position(file, line);
        if (!source_position_and_address.has_value())
            return IterationDecision::Continue;

        result = source_position_and_address;
        result.value().address += lib.base_address;
        return IterationDecision::Break;
    });
    return result;
}

Optional<DebugInfo::SourcePosition> ProcessInspector::get_source_position(FlatPtr address) const
{
    auto* lib = library_at(address);
    if (!lib)
        return {};
    return lib->debug_info->get_source_position(address - lib->base_address);
}

}