mirror of https://github.com/zeldaret/tp.git
103 lines
2.8 KiB
Python
103 lines
2.8 KiB
Python
import os
|
|
|
|
from typing import Optional, IO, List
|
|
|
|
from . import elf
|
|
from .util import *
|
|
|
|
class Section:
|
|
id: int
|
|
header: elf.SectionHeader
|
|
name: Optional[str]
|
|
data: bytearray
|
|
addr: int
|
|
size: int
|
|
|
|
def __init__(self, header: elf.SectionHeader):
|
|
self.header = header
|
|
self.name = None
|
|
self.data = None
|
|
self.size = header.sh_size
|
|
self.section = None
|
|
self.addr = None
|
|
self.file_addr = None
|
|
self.alignment = header.sh_addralign
|
|
self.object = None
|
|
|
|
|
|
def getVirtualAddr(self, offset=0):
|
|
return self.addr + offset
|
|
|
|
class ProgBitsSection(Section):
|
|
def __init__(self, header: elf.SectionHeader, file: IO):
|
|
super().__init__(header)
|
|
|
|
if header.sh_size > 0:
|
|
file.seek(header.sh_offset, os.SEEK_SET)
|
|
self.data = bytearray(file.read(header.sh_size))
|
|
|
|
class NoBitsSection(Section):
|
|
def __init__(self, header: elf.SectionHeader):
|
|
super().__init__(header)
|
|
|
|
|
|
class StringTableSection(ProgBitsSection):
|
|
def __init__(self, header: elf.SectionHeader, file: IO):
|
|
super().__init__(header, file)
|
|
|
|
def readString(self, offset: int) -> Optional[str]:
|
|
return parse_null_string(self.data[offset:])
|
|
|
|
|
|
class SymbolTableSection(Section):
|
|
symbols: List[elf.Symbol]
|
|
|
|
def __init__(self, header: elf.SectionHeader, file: IO):
|
|
super().__init__(header)
|
|
self.symbols = []
|
|
|
|
if header.sh_entsize != 0x10:
|
|
fail("symtab section: invalid entry size")
|
|
if header.sh_size % header.sh_entsize != 0:
|
|
fail("symtab section: invalid size (not divisible by entry size) ")
|
|
|
|
count = header.sh_size // header.sh_entsize
|
|
file.seek(header.sh_offset, os.SEEK_SET)
|
|
for _ in range(count):
|
|
symbol = elf.Symbol()
|
|
symbol.read(file)
|
|
self.symbols.append(symbol)
|
|
|
|
RELOCATION_NAMES = {
|
|
0x0: "R_PPC_NONE",
|
|
0x1: "R_PPC_ADDR32",
|
|
0x3: "R_PPC_ADDR16",
|
|
0x4: "R_PPC_ADDR16_LO",
|
|
0x5: "R_PPC_ADDR16_HI",
|
|
0x6: "R_PPC_ADDR16_HA",
|
|
0xA: "R_PPC_REL24",
|
|
0xB: "R_PPC_REL14",
|
|
0x18: "R_PPC_UADDR32",
|
|
0x6D: "R_PPC_EMB_SDA21",
|
|
}
|
|
|
|
class RelocationASection(Section):
|
|
relocations: List[elf.RelA]
|
|
|
|
def __init__(self, header: elf.SectionHeader, file: IO):
|
|
super().__init__(header)
|
|
self.relocations = []
|
|
|
|
if header.sh_entsize != 0x0C:
|
|
fail("relocation section: invalid entry size")
|
|
if header.sh_size % header.sh_entsize != 0:
|
|
fail("relocation section: invalid size (not divisible by entry size) ")
|
|
|
|
count = header.sh_size // header.sh_entsize
|
|
file.seek(header.sh_offset, os.SEEK_SET)
|
|
for _ in range(count):
|
|
rela = elf.RelA()
|
|
rela.read(file)
|
|
self.relocations.append(rela)
|
|
|