Passed
Push — 0.6.x ( 9a1948...a98caa )
by Shinji
03:23 queued 01:32
created

createContainerAwarePath()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file is part of the reliforp/reli-prof package.
5
 *
6
 * (c) sji <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Reli\Lib\Elf\Process;
15
16
use Reli\Lib\Elf\Parser\ElfParserException;
17
use Reli\Lib\Elf\SymbolResolver\SymbolResolverCreatorInterface;
18
use Reli\Lib\Process\MemoryMap\ProcessMemoryMap;
19
use Reli\Lib\Process\MemoryMap\ProcessModuleMemoryMap;
20
use Reli\Lib\Process\MemoryReader\MemoryReaderInterface;
21
22
final class ProcessModuleSymbolReaderCreator
23
{
24
    public function __construct(
25
        private SymbolResolverCreatorInterface $symbol_resolver_creator,
26
        private MemoryReaderInterface $memory_reader
27
    ) {
28
    }
29
30
    public function createModuleReaderByNameRegex(
31
        int $pid,
32
        ProcessMemoryMap $process_memory_map,
33
        string $regex,
34
        ?string $binary_path,
35
        ?int $tls_block_address = null
36
    ): ?ProcessModuleSymbolReader {
37
        $memory_areas = $process_memory_map->findByNameRegex($regex);
38
        if ($memory_areas === []) {
39
            return null;
40
        }
41
        $module_memory_map = new ProcessModuleMemoryMap($memory_areas);
42
43
        $module_name = current($memory_areas)->name;
44
        $path = $binary_path ?? $this->createContainerAwarePath($pid, $module_name);
45
        try {
46
            $symbol_resolver = $this->symbol_resolver_creator->createLinearScanResolverFromPath($path);
47
            return new ProcessModuleSymbolReader(
48
                $pid,
49
                $symbol_resolver,
50
                $module_memory_map,
51
                $this->memory_reader,
52
                $tls_block_address
53
            );
54
        } catch (ElfParserException $e) {
55
            try {
56
                $symbol_resolver = $this->symbol_resolver_creator->createDynamicResolverFromPath($path);
57
                return new ProcessModuleSymbolReader(
58
                    $pid,
59
                    $symbol_resolver,
60
                    $module_memory_map,
61
                    $this->memory_reader,
62
                    $tls_block_address
63
                );
64
            } catch (ElfParserException $e) {
65
                $symbol_resolver = $this->symbol_resolver_creator->createDynamicResolverFromProcessMemory(
66
                    $this->memory_reader,
67
                    $pid,
68
                    $module_memory_map
69
                );
70
                return new ProcessModuleSymbolReader(
71
                    $pid,
72
                    $symbol_resolver,
73
                    $module_memory_map,
74
                    $this->memory_reader,
75
                    $tls_block_address
76
                );
77
            }
78
        }
79
    }
80
81
    private function createContainerAwarePath(int $pid, string $path): string
82
    {
83
        return "/proc/{$pid}/root{$path}";
84
    }
85
}
86