tp/tools/libdol2asm/data/function/sinit.py

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)