Skip to content

[WIP] Handle x86 MSVC jumptables#195

Open
1superchip wants to merge 6 commits intosimonlindholm:mainfrom
1superchip:x86-msvc-jumptable-fixup
Open

[WIP] Handle x86 MSVC jumptables#195
1superchip wants to merge 6 commits intosimonlindholm:mainfrom
1superchip:x86-msvc-jumptable-fixup

Conversation

@1superchip
Copy link
Collaborator

@1superchip 1superchip commented Apr 30, 2025

This is a draft pr that implements handling of MSVC jumptables for x86. It currently requires diff function symbols to work properly as that is needed for the labels to be processed but it should not require that in the long run.

A small issue with this is that if there are multiple text sections, arrows will be shown in each text section. There was also an issue with objdump not emitting proper information for jumptables in a 2nd text section if the first section had a jump table.

objdump output of the jumptable:
image

objdump output of the assembly that is referenced from the jumptable:
image

An image of the final result:
image

We need <$Lnum> in the 2nd image to get the location.

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

target_line_num: Union[int, None]
Copy link
Owner

Choose a reason for hiding this comment

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

Suggested change
target_line_num: Union[int, None]
target_line_num: Optional[int]


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

# Remove "-0x..." from older objdump relocations
Copy link
Owner

Choose a reason for hiding this comment

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

What does older mean, are we talking about different compiler or objdump versions, or is it older in the sense of us not yet having processed them?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Older objdump versions such as 2.39 emit -0x... in relocations relative to the section start
image
image

The binutils that decomp.me uses is GNU objdump (GNU Binutils) 2.41.90.20240122 which does not emit the -0x....

if target_line_num:
line.original = line.original.replace(
orig_jump_table_target, hex(target_line_num).replace("0x", "")
)
Copy link
Owner

Choose a reason for hiding this comment

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

Can we set line.original = ".dword\t" + hex(...) instead? Search-replace always feels fragile to me

# 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.

# 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)":
lines.remove(line)
Copy link
Owner

Choose a reason for hiding this comment

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

.remove(...) loops over the entire lines list and checks dataclass equality, which is slow and can have false positives. We could instead e.g. do

indices_to_delete = []
for index, ... in enumerate(lines):
    if ...:
        indices_to_delete.append(index)
for index in reversed(indices_to_delete):
    del lines[index]

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] = lines.index(line)
Copy link
Owner

Choose a reason for hiding this comment

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

... and then this would let us use index instead of finding the line anew because lines has not yet been re-indexed

@simonlindholm
Copy link
Owner

(Should [WIP] be removed from the title?)

1superchip and others added 3 commits February 5, 2026 11:56
Co-authored-by: Simon Lindholm <simon.lindholm10@gmail.com>
Co-authored-by: Simon Lindholm <simon.lindholm10@gmail.com>
Co-authored-by: Simon Lindholm <simon.lindholm10@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants