summaryrefslogtreecommitdiff
path: root/tools/libelf/symbol.py
blob: c94617a5a154d1526a38677405b3c7ab39635df2 (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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
from typing import Optional, List, IO
from pathlib import Path

from . import elf
from .section import *

class Symbol:
    header: elf.Symbol
    name: Optional[str]
    bind: int
    type: int
    visibility: int
    addr: Optional[int]
    used: int
    section: Optional[Section]

    def __init__(self, header: elf.Symbol, name: Optional[str]):
        self.header = header
        self.name = name
        self.bind = elf.ST_BIND(header.st_info)
        self.type = elf.ST_TYPE(header.st_info)
        self.visibility = elf.ST_VISIBILITY(header.st_other)
        self.size = header.st_size
        self.object = None
        self.addr = None
        self.used = 0
        self.section = None
        self.object = None

    def isSection(self):
        return self.type == elf.STT_SECTION

    def isObject(self):
        return self.type == elf.STT_OBJECT

    def isFile(self):
        return self.type == elf.STT_FILE

    def isBindLocal(self):
        return self.bind == elf.STB_LOCAL

    def isBindGlobal(self):
        return self.bind == elf.STB_GLOBAL

    def getSection(self):
        fail("Symbol is not associated to any section")


class NullSymbol(Symbol):
    def __init__(self, header: elf.Symbol):
        super().__init__(header, None)

class UndefSymbol(Symbol):
    reference: Optional[Symbol]
    def __init__(self, header: elf.Symbol, name: Optional[str]):
        super().__init__(header, name)
        self.reference = None

    def resolveAddress(self):
        assert self.reference
        self.reference.resolveAddress()
        self.addr = self.reference.addr

    def getSection(self):
        assert self.reference
        return self.reference.getSection()

class AbsoluteSymbol(Symbol):
    address: int
    def __init__(self, header: elf.Symbol, name: Optional[str], value: int):
        super().__init__(header, name)
        self.address = value

    def resolveAddress(self):
        self.addr = self.address

class OffsetSymbol(Symbol):
    section: Section
    offset: int
    def __init__(self, header: elf.Symbol, name: Optional[str], section: Section, offset: int):
        super().__init__(header, name)
        self.section = section
        self.offset = offset

    def resolveAddress(self):
        self.addr = self.section.addr + self.offset

    def getSection(self):
        return  self.section