mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-07-11 05:04:40 -04:00
.dead section fix
This commit is contained in:
@@ -2,3 +2,4 @@
|
||||
from .base import *
|
||||
from .asm import *
|
||||
from .ret import *
|
||||
from .sinit import *
|
||||
|
||||
@@ -7,33 +7,11 @@ 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 *
|
||||
|
||||
"""
|
||||
@dataclass(eq=False)
|
||||
class Block(ArbitraryData):
|
||||
sda_hack_references: Set[int] = field(default=None, repr=False)
|
||||
|
||||
def _get_internal_references(self, context, symbol_table):
|
||||
collector = AccessCollector([])
|
||||
for x in collector.execute_generator(self.addr, self.data, self.size):
|
||||
pass
|
||||
sda_hack_symbols = [symbol_table[self._module, x]
|
||||
for x in collector.sda_hack_references]
|
||||
self.sda_hack_references = set([
|
||||
(x._module, x.addr)
|
||||
for x in sda_hack_symbols
|
||||
if x
|
||||
])
|
||||
symbols = [
|
||||
symbol_table[self._module, x.addr]
|
||||
for x in collector.accesses.values()
|
||||
]
|
||||
return set([(x._module, x.addr) for x in symbols if x])
|
||||
"""
|
||||
|
||||
@dataclass
|
||||
class Block():
|
||||
identifier: Identifier
|
||||
@@ -53,7 +31,6 @@ class Block():
|
||||
return None
|
||||
return self.identifier.label
|
||||
|
||||
from .. import static_analyze
|
||||
|
||||
@dataclass(eq=False)
|
||||
class ASMFunction(Function):
|
||||
@@ -63,6 +40,7 @@ class ASMFunction(Function):
|
||||
data: bytearray = None
|
||||
|
||||
def gather_references(self, context, valid_range):
|
||||
"""
|
||||
addrs = static_analyze.function(self.data, self.addr, self.size)
|
||||
function_range = AddressRange(self.start, self.end)
|
||||
self.references = [
|
||||
@@ -70,7 +48,25 @@ class ASMFunction(Function):
|
||||
for addr in addrs.values()
|
||||
if addr in valid_range and not addr in function_range
|
||||
]
|
||||
"""
|
||||
|
||||
collector = AccessCollector([])
|
||||
for i, addr in collector.execute_generator(self.addr, self.data, self.size):
|
||||
pass
|
||||
|
||||
function_range = AddressRange(self.start, self.end)
|
||||
self.references = [
|
||||
access.addr
|
||||
for access in collector.accesses.values()
|
||||
if access.addr in valid_range and not access.addr in function_range
|
||||
]
|
||||
|
||||
self.test_references = [
|
||||
(access.at, access.addr)
|
||||
for access in collector.accesses.values()
|
||||
if access.addr in valid_range and not access.addr in function_range
|
||||
]
|
||||
|
||||
async def export_function_body(self, exporter, builder: AsyncBuilder):
|
||||
await builder.write(f" {{")
|
||||
await builder.write(f"\tnofralloc")
|
||||
@@ -80,6 +76,15 @@ class ASMFunction(Function):
|
||||
async def export_declaration(self, exporter, builder: AsyncBuilder):
|
||||
assert self.padding == 0
|
||||
|
||||
|
||||
for k,v in self.test_references:
|
||||
symbol_name = "???"
|
||||
symbol = exporter.gst[-1, v]
|
||||
if symbol:
|
||||
symbol_name = symbol.label
|
||||
await builder.write(f"//\t{k:08X}: {v:08X} ({symbol_name})")
|
||||
|
||||
|
||||
await builder.write("#pragma push")
|
||||
await builder.write("#pragma optimization_level 0")
|
||||
await builder.write("#pragma optimizewithasm off")
|
||||
@@ -101,10 +106,6 @@ class ASMFunction(Function):
|
||||
|
||||
blocks = []
|
||||
for symbol in group:
|
||||
#block = Block(
|
||||
# Identifier("lbl", symbol.addr, None),
|
||||
# symbol.addr, symbol.size,
|
||||
# data=section.data_for_symbol(symbol))
|
||||
block = Block(
|
||||
Identifier("lbl", symbol.addr, None),
|
||||
symbol.addr, symbol.size,
|
||||
|
||||
@@ -24,6 +24,40 @@ class Function(Symbol):
|
||||
template_index: int = -1
|
||||
asm: bool = False
|
||||
|
||||
@property
|
||||
def uses_any_templates(self):
|
||||
if self.func_name and self.func_name.has_template:
|
||||
return True
|
||||
|
||||
is_templated = [False]
|
||||
def callback(tp, depth):
|
||||
if isinstance(tp, NamedType):
|
||||
is_templated[0] |= tp.has_template
|
||||
if is_templated[0]:
|
||||
return True
|
||||
|
||||
if self.return_type:
|
||||
self.return_type.traverse(callback, 0)
|
||||
for arg_type in self.argument_types:
|
||||
arg_type.traverse(callback, 0)
|
||||
|
||||
return is_templated[0]
|
||||
|
||||
@property
|
||||
def uses_class_template(self):
|
||||
return self.func_name and self.func_name.has_template
|
||||
|
||||
@property
|
||||
def is_static(self):
|
||||
static = super().is_static
|
||||
if not static:
|
||||
return False
|
||||
|
||||
if not self.func_name:
|
||||
return True
|
||||
|
||||
return not self.uses_any_templates
|
||||
|
||||
@property
|
||||
def label(self):
|
||||
return self.identifier.label
|
||||
@@ -96,13 +130,23 @@ class Function(Symbol):
|
||||
without_template: bool = False,
|
||||
comment_arguments: bool = False,
|
||||
template_args: List[str] = None):
|
||||
# prints internal references for the function
|
||||
if False:
|
||||
if not forward:
|
||||
refs = self.internal_references(exporter.context, exporter.gst)
|
||||
await builder.write(f"/* internal references (count {len(refs)})")
|
||||
for ref in refs:
|
||||
await builder.write(f"// {ref.addr:08X} {ref.label}")
|
||||
await builder.write(f"// {self.is_static} {self.uses_any_templates}")
|
||||
|
||||
lines = []
|
||||
def callback(tp, depth):
|
||||
pad = '\t' * depth
|
||||
template = False
|
||||
if isinstance(tp, NamedType):
|
||||
template = tp.has_template
|
||||
lines.append(f"// {pad} {tp.type()} {template}")
|
||||
|
||||
if self.return_type:
|
||||
self.return_type.traverse(callback, 0)
|
||||
for arg_type in self.argument_types:
|
||||
arg_type.traverse(callback, 0)
|
||||
|
||||
for line in lines:
|
||||
await builder.write(line)
|
||||
|
||||
declspec = "extern \"C\" "
|
||||
if not original and self.is_demangled():
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
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"#pragma section \".ctors$15\"")
|
||||
await builder.write(f"__declspec(section \".ctors$15\") void* const _ctors_{self.addr:08X} = (void*){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)
|
||||
Reference in New Issue
Block a user