Passed
Push — master ( 46a849...6d6c3a )
by Shinji
01:23
created

createDynamicResolverFromProcessMemory()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 26
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 19
nc 2
nop 3
dl 0
loc 26
rs 9.6333
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file is part of the sj-i/php-profiler 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 PhpProfiler\Lib\Elf\SymbolResolver;
15
16
use PhpProfiler\Lib\Binary\BinaryReader;
17
use PhpProfiler\Lib\Binary\ProcessMemoryByteReader;
18
use PhpProfiler\Lib\Binary\StringByteReader;
19
use PhpProfiler\Lib\Elf\Parser\Elf64Parser;
20
use PhpProfiler\Lib\Elf\Parser\ElfParserException;
21
use PhpProfiler\Lib\File\FileReaderInterface;
22
use PhpProfiler\Lib\Process\MemoryMap\ProcessMemoryArea;
23
use PhpProfiler\Lib\Process\MemoryReader\MemoryReaderInterface;
24
25
/**
26
 * Class SymbolResolverCreator
27
 * @package PhpProfiler\Lib\Elf
28
 */
29
final class Elf64SymbolResolverCreator implements SymbolResolverCreatorInterface
30
{
31
    private FileReaderInterface $file_reader;
32
33
    /**
34
     * SymbolResolverCreator constructor.
35
     * @param FileReaderInterface $file_reader
36
     */
37
    public function __construct(FileReaderInterface $file_reader)
38
    {
39
        $this->file_reader = $file_reader;
40
    }
41
42
    /**
43
     * @param string $path
44
     * @return Elf64LinearScanSymbolResolver
45
     * @throws ElfParserException
46
     */
47
    public function createLinearScanResolverFromPath(string $path): Elf64LinearScanSymbolResolver
48
    {
49
        $binary_raw = $this->file_reader->readAll($path);
50
        if ($binary_raw === '') {
51
            throw new ElfParserException('cannot read ELF binary');
52
        }
53
        $binary = new StringByteReader($binary_raw);
54
        $parser = new Elf64Parser(new BinaryReader());
55
        $elf_header = $parser->parseElfHeader($binary);
56
        $section_header = $parser->parseSectionHeader($binary, $elf_header);
57
        $symbol_table_section_header_entry = $section_header->findSymbolTableEntry();
58
        $string_table_section_header_entry = $section_header->findStringTableEntry();
59
        if (is_null($symbol_table_section_header_entry)) {
60
            throw new ElfParserException('cannot find symbol table from section header table');
61
        }
62
        if (is_null($string_table_section_header_entry)) {
63
            throw new ElfParserException('cannot find string table from section header table');
64
        }
65
        $symbol_table = $parser->parseSymbolTableFromSectionHeader($binary, $symbol_table_section_header_entry);
66
        $string_table = $parser->parseStringTableFromSectionHeader($binary, $string_table_section_header_entry);
67
        return new Elf64LinearScanSymbolResolver($symbol_table, $string_table);
68
    }
69
70
    /**
71
     * @param string $path
72
     * @return Elf64DynamicSymbolResolver
73
     * @throws ElfParserException
74
     */
75
    public function createDynamicResolverFromPath(string $path): Elf64DynamicSymbolResolver
76
    {
77
        $binary_raw = $this->file_reader->readAll($path);
78
        if ($binary_raw === '') {
79
            throw new ElfParserException('cannot read ELF binary');
80
        }
81
        $binary = new StringByteReader($binary_raw);
82
        $parser = new Elf64Parser(new BinaryReader());
83
        return Elf64DynamicSymbolResolver::load($parser, $binary);
84
    }
85
86
    /**
87
     * @param MemoryReaderInterface $memory_reader
88
     * @param int $pid
89
     * @param ProcessMemoryArea[] $memory_area
90
     * @return Elf64DynamicSymbolResolver
91
     * @throws ElfParserException
92
     */
93
    public function createDynamicResolverFromProcessMemory(
94
        MemoryReaderInterface $memory_reader,
95
        int $pid,
96
        array $memory_area
97
    ): Elf64DynamicSymbolResolver {
98
        $php_binary = new ProcessMemoryByteReader($memory_reader, $pid, $memory_area);
99
        $parser = new Elf64Parser(new BinaryReader());
100
        $elf_header = $parser->parseElfHeader($php_binary);
101
        $elf_program_header = $parser->parseProgramHeader($php_binary, $elf_header);
102
        $elf_dynamic_array = $parser->parseDynamicStructureArray($php_binary, $elf_program_header->findDynamic()[0]);
103
        $php_binary->toggle(true);
104
        $elf_string_table = $parser->parseStringTable($php_binary, $elf_dynamic_array);
105
        $elf_gnu_hash_table = $parser->parseGnuHashTable($php_binary, $elf_dynamic_array);
106
        if (is_null($elf_gnu_hash_table)) {
107
            throw new ElfParserException('cannot find gnu hash table');
108
        }
109
        $elf_symbol_table = $parser->parseSymbolTableFromDynamic(
110
            $php_binary,
111
            $elf_dynamic_array,
112
            $elf_gnu_hash_table->getNumberOfSymbols()
113
        );
114
        $php_binary->toggle(false);
115
        return new Elf64DynamicSymbolResolver(
116
            $elf_symbol_table,
117
            $elf_gnu_hash_table,
118
            $elf_string_table
119
        );
120
    }
121
}
122