mirror of https://github.com/zeldaret/tp.git
65 lines
1.9 KiB
Python
65 lines
1.9 KiB
Python
import struct
|
|
|
|
from dataclasses import dataclass, field
|
|
from typing import List, Set, Dict
|
|
from pathlib import Path
|
|
|
|
from ...builder import AsyncBuilder
|
|
from ...disassemble import AccessCollector
|
|
from ... import util
|
|
from .. import static_analyze
|
|
from ..base import *
|
|
from ..symbol import *
|
|
from .base import *
|
|
from .asm import *
|
|
|
|
@dataclass(eq=False)
|
|
class SInitFunction(ASMFunction):
|
|
async def export_declaration(self, exporter, builder: AsyncBuilder):
|
|
await super().export_declaration(exporter, builder)
|
|
|
|
await builder.write("#pragma push")
|
|
await builder.write("#pragma force_active on")
|
|
await builder.write(f"REGISTER_CTORS(0x{self.addr:08X}, {self.label});")
|
|
await builder.write("#pragma pop")
|
|
await builder.write("")
|
|
|
|
@staticmethod
|
|
def create(section, group):
|
|
# TODO: This code is the same as ASMFunction.create
|
|
first = group[0]
|
|
last = group[-1]
|
|
start = first.start
|
|
end = last.end
|
|
|
|
blocks = []
|
|
for symbol in group:
|
|
block = Block(
|
|
Identifier("lbl", symbol.addr, None),
|
|
symbol.addr, symbol.size,
|
|
)
|
|
blocks.append(block)
|
|
|
|
# Calculate additional padding from zeros at the end of the function
|
|
data = section.get_data(start, end)
|
|
end_padding = 0
|
|
last_data = list(util.chunks(data, 4))
|
|
for x in last_data[::-1]:
|
|
if struct.unpack('>I', x)[0] != 0:
|
|
break
|
|
end_padding += 4
|
|
|
|
if end_padding > 0:
|
|
data = data[:-end_padding]
|
|
end -= end_padding
|
|
|
|
return SInitFunction(
|
|
Identifier("func", start, first.name),
|
|
addr=start,
|
|
size=end - start,
|
|
padding=last.padding + end_padding,
|
|
alignment=0,
|
|
blocks=blocks,
|
|
source=first.source,
|
|
data=data)
|