Skip to content
Open
65 changes: 65 additions & 0 deletions diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -2077,6 +2077,9 @@ def process_reloc(self, row: str, prev: str) -> Tuple[str, Optional[str]]:
offset = False
addr_imm = None

if prev == "add\t%al,(%eax)" and "dir32" in row:
return f".dword\t{row.split()[-1]}", repl

# Calls

# Example lcall $0x0, $0x00
Expand Down Expand Up @@ -2201,6 +2204,68 @@ def process_reloc(self, row: str, prev: str) -> Tuple[str, Optional[str]]:
def is_end_of_function(self, mnemonic: str, args: str) -> bool:
return mnemonic == "ret"

def _post_process_jump_tables(self, lines: List["Line"]) -> None:

# Handle jump tables produced by MSVC.
# MSVC jump table labels are in the format of "$L{NUM}"

# Removes extra "add\t%al,(%eax)" which correspond to an existing jumptable entry
# and adds branch arrows to the jump table entries

# This will have errors for multiple text sections as objdump (at least 2.38) doesn't emit
# the correct labels for sections that are not the first

jump_table_targets: List[str] = [] # target_label
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems to be unused

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like it. I have the targets stored to it but they are never read from it.


labels: Dict[str, int] = {} # line number for each label

was_previous_jumptable_entry = False

indices_to_delete = []

for index, line in enumerate(lines):
if line.original.startswith(".dword"):

orig_jump_table_target: str = line.original.split(".dword")[1].strip()

# Remove "-0x..." from older objdump relocations
jump_table_target = re.sub(r"-0x[0-9a-f]+", "", orig_jump_table_target)

jump_table_targets.append(jump_table_target)

# If a line begins with ".dword", it is a jumptable
was_previous_jumptable_entry = True

target_line_num: Optional[int]
try:
target_line_num = lines[
labels[jump_table_target + ":"] + 1
].line_num
except Exception:
target_line_num = None

if target_line_num is not None:
line.original = ".dword\t" + hex(target_line_num)[2:]

line.branch_target = target_line_num
elif was_previous_jumptable_entry:
# if the previous line was a jumptable and the current line is "add\t%al,(%eax)"
# this is the 2nd half of the previous jumptable entry
if line.original == "add\t%al,(%eax)":
indices_to_delete.append(index)

was_previous_jumptable_entry = False
elif line.mnemonic == "<label>" and line.original.startswith("$L"):
# If this is a label that is an MSVC jumptable label "$L..."
# add it to the labels list
labels[line.original] = index

for index in reversed(indices_to_delete):
del lines[index]

def post_process(self, lines: List["Line"]) -> None:
self._post_process_jump_tables(lines)


class AsmProcessorSH2(AsmProcessor):
def __init__(self, config: Config) -> None:
Expand Down