.dead section fix

This commit is contained in:
Julgodis
2021-03-31 23:22:32 +02:00
parent 2404fb33c7
commit b6eed5208d
8427 changed files with 1951354 additions and 667431 deletions
@@ -2,3 +2,4 @@
from .base import *
from .asm import *
from .ret import *
from .sinit import *
+29 -28
View File
@@ -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,
+51 -7
View File
@@ -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():
+65
View File
@@ -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)