Skip to content

Commit

Permalink
x86/generator: [fix] incorrect selection of instructions when patchin…
Browse files Browse the repository at this point in the history
…g undef flags; refs #64
  • Loading branch information
OleksiiOleksenko committed Apr 11, 2023
1 parent 744ac9b commit 8102ded
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ def main() -> int:
return 0

if args.subparser_name == "download_spec":
get_downloader(args.architecture, args.extensions, args.outfile).run()
get_downloader(args.architecture, args.extensions, args.outfile).run() # type: ignore
return 0

raise Exception("Unreachable")
Expand Down
20 changes: 17 additions & 3 deletions src/x86/x86_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import math
import re
import random
import copy
from typing import List, Dict, Set, Optional, Tuple
from subprocess import run

Expand Down Expand Up @@ -718,14 +719,25 @@ def run_on_test_case(self, test_case: TestCase) -> None:

def find_flags_patch(self, undef_flags, flags_to_set) -> List[Instruction]:
"""
Find an instruction that would overwrite the undefined flags
Find an instruction sequence that would overwrite a list of flags
:param undef_flags: list of undefined flags that have to be overwritten
by the patch instructions
:param flags_to_set: list of flags that will be read by one of the following instructions,
and thus should not be set to the undef state by the patch. This should be always
a superset of or the same as undef_flags.
:return: list of instructions that overwrite the undefined flags
"""
org_undef = copy.deepcopy(undef_flags)
patches: List[Instruction] = []
for instruction_spec in self.patch_candidates:
patch = self.generator.generate_instruction(instruction_spec)
patch_flags = patch.get_flags_operand()
assert patch_flags
new_undef_flags = [i for i in patch_flags.get_undef_flags() if i in flags_to_set]
new_undef_flags = [
i for i in patch_flags.get_undef_flags()
if i not in undef_flags and i in flags_to_set
]
not_patched_flags = [i for i in undef_flags if i not in patch_flags.get_write_flags()]

if not new_undef_flags and not_patched_flags != undef_flags:
Expand All @@ -735,7 +747,9 @@ def find_flags_patch(self, undef_flags, flags_to_set) -> List[Instruction]:
break

if undef_flags:
raise GeneratorException(f"Could not find an instruction to patch flags {undef_flags}")
raise GeneratorException("Could not find an instruction to patch flags.\n"
f" Initial flags to be patched: {org_undef}\n"
f" Flags for which a patch was not found: {undef_flags}")

return patches

Expand Down

0 comments on commit 8102ded

Please sign in to comment.