Skip to content

Commit

Permalink
Restructure layout for mnemonic parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
hainest committed Apr 26, 2024
1 parent a29f32a commit 4fdb8c5
Show file tree
Hide file tree
Showing 12 changed files with 358 additions and 266 deletions.
7 changes: 0 additions & 7 deletions instructionAPI/capstone/aarch64.py

This file was deleted.

Empty file.
14 changes: 14 additions & 0 deletions instructionAPI/capstone/aarch64/mnemonics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
def _read_capstone_mnemonics(file:str):
return []

def _read_dyninst_mnemonics(file:str):
return []

class mnemonics:
def __init__(self, cap_dir:str, dyn_dir:str):
self.dyninst_prefix = "aarch64_op"
self.missing = None
self.pseudo = None
self.capstone = _read_capstone_mnemonics(cap_dir + "/arch/AArch64/AArch64GenCSMappingInsnName.inc")
self.dyninst = _read_dyninst_mnemonics(dyn_dir + "/common/h/mnemonics/aarch64_entryIDs.h")
self.aliases = None
12 changes: 0 additions & 12 deletions instructionAPI/capstone/capstone.py

This file was deleted.

56 changes: 0 additions & 56 deletions instructionAPI/capstone/import.py

This file was deleted.

104 changes: 104 additions & 0 deletions instructionAPI/capstone/import_mnemonics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import argparse
import x86.mnemonics
import aarch64.mnemonics
import ppc.mnemonics

parser = argparse.ArgumentParser(
description="Translate Capstone's instructions into Dyninst instructions",
epilog="""
The mnemonics are stored in the output file 'mnemonics.<arch>'. This can be directly copied to
the appropriate architecture file in Dyninst (e.g., common/mnemonics/x86_entryIDs.h).
"""
)
parser.add_argument(
"--capstone-dir",
type=str,
required=True,
help="Capstone source directory (e.g., /capstone-engine/capstone/)"
)
parser.add_argument(
"--dyninst-dir",
type=str,
required=True,
help="Dyninst source directory (e.g., /dyninst/src/)"
)

parser.add_argument("--arch", type=str, choices=["x86","aarch64","ppc"], default="x86")
args = parser.parse_args()

print("Processing mnemonics for {0:s}".format(args.arch))

if args.arch == "x86":
mnemonics = x86.mnemonics.mnemonics(args.capstone_dir, args.dyninst_dir)
elif args.arch == "aarch64":
mnemonics = aarch64.mnemonics.mnemonics(args.capstone_dir, args.dyninst_dir)
elif args.arch == "ppc":
mnemonics = ppc.mnemonics.mnemonics(args.capstone_dir, args.dyninst_dir)

with open("mnemonics.{0:s}".format(args.arch), "w") as f:
if mnemonics.pseudo is not None:
for p in mnemonics.pseudo:
f.write("{0:s}_{1:s}, /* pseudo mnemonic */\n".format(mnemonics.dyninst_prefix, p))

if mnemonics.aliases is not None:
for m in mnemonics.capstone:
if m not in mnemonics.aliases:
f.write("{0:s}_{1:s},\n".format(mnemonics.dyninst_prefix, m))
continue

if not mnemonics.aliases[m]["seen"]:
f.write("{0:s}_{1:s},\n".format(mnemonics.dyninst_prefix, m))
mnemonics.aliases[m]["seen"] = True
for a in mnemonics.aliases[m]["values"]:
f.write("{0:s}_{1:s} = {0:s}_{2:s},\n".format(mnemonics.dyninst_prefix, a, m))
mnemonics.aliases[a]["seen"] = True

# New mnemonics added from Capstone
print("New mnemonics added from Capstone: ", end='')
capset = set(mnemonics.capstone)
dynset = set(mnemonics.dyninst)
new_mnemonics = capset - dynset
if len(new_mnemonics) > 0:
for m in new_mnemonics:
print("\t{0:s}".format(m))
else:
print("None")

# Missing aliases
if mnemonics.aliases is not None:
print("Known aliases not in Capstone: ", end='')
unseen_aliases = [a for a in mnemonics.aliases if not mnemonics.aliases[a]["seen"]]
if len(unseen_aliases) > 0:
for a in unseen_aliases:
print("\tDidn't find '{0:s}', aliased with ".format(a), mnemonics.aliases[a]["values"])
else:
print("None")

# Known mnemonics missing from Capstone
if mnemonics.missing is not None:
print("Mnemonics known to be missing from Capstone: ", end='')
if len(mnemonics.missing) > 0:
print()
for m in mnemonics.missing:
print("\t{0:s}".format(m))
else:
print("None")

# In Dyninst, but not Capstone
print("Mnemonics found in Dyninst, but not Capstone (likely an error!!): ", end='')
missing = dynset - capset # implicitly ignores pseudo registers

if mnemonics.aliases is not None:
# Ignore seen aliases
missing -= set([a for a in mnemonics.aliases if mnemonics.aliases[a]["seen"]])

if mnemonics.missing is not None:
# Ignore known missing
missing -= set(mnemonics.missing)

if len(missing) > 0:
print()
for m in missing:
print("\t{0:s}".format(m))
else:
print("None")
8 changes: 0 additions & 8 deletions instructionAPI/capstone/ppc.py

This file was deleted.

Empty file.
14 changes: 14 additions & 0 deletions instructionAPI/capstone/ppc/mnemonics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
def _read_capstone_mnemonics(file:str):
return []

def _read_dyninst_mnemonics(file:str):
return []

class mnemonics:
def __init__(self, cap_dir:str, dyn_dir:str):
self.dyninst_prefix = "power_op"
self.missing = None
self.pseudo = None
self.capstone = _read_capstone_mnemonics(cap_dir + "/arch/PowerPC/PPCGenCSMappingInsnName.inc")
self.dyninst = _read_dyninst_mnemonics(dyn_dir + "/common/h/mnemonics/ppc_entryIDs.h")
self.aliases = None

0 comments on commit 4fdb8c5

Please sign in to comment.