#!/usr/bin/python # print list of instructions LLVM inc files, for Capstone disassembler. # this will be put into capstone/.h # by Nguyen Anh Quynh, 2019 import sys if len(sys.argv) == 1: print("Syntax: %s " %sys.argv[0]) sys.exit(1) print("""/* Capstone Disassembly Engine, http://www.capstone-engine.org */ /* This is auto-gen data for Capstone disassembly engine (www.capstone-engine.org) */ /* By Nguyen Anh Quynh , 2013-2019 */ """) # lib/Target/X86/X86GenAsmMatcher.inc # static const MatchEntry MatchTable1[] = { # { 0 /* aaa */, X86::AAA, Convert_NoOperands, Feature_Not64BitMode, { }, }, # extract insn from GenAsmMatcher Table # return (arch, mnem, insn_id) def extract_insn(line): tmp = line.split(',') insn_raw = tmp[1].strip() insn_mnem = tmp[0].split(' ')[3] # X86 mov.s if '.' in insn_mnem: tmp = insn_mnem.split('.') insn_mnem = tmp[0] tmp = insn_raw.split('::') arch = tmp[0] # AArch64 -> ARM64 if arch.upper() == 'AARCH64': arch = 'ARM64' return (arch, insn_mnem, tmp[1]) # extract all insn lines from GenAsmMatcher # return arch, first_insn, insn_id_list def extract_matcher(filename): f = open(filename) lines = f.readlines() f.close() match_count = 0 mnem_list = [] insn_id_list = {} arch = None first_insn = None pattern = None # first we try to find Table1, or Table0 for line in lines: if 'MatchEntry MatchTable0[] = {' in line.strip(): pattern = 'MatchEntry MatchTable0[] = {' elif 'MatchEntry MatchTable1[] = {' in line.strip(): pattern = 'MatchEntry MatchTable1[] = {' # last pattern, done break # 1st enum is register enum for line in lines: line = line.rstrip() if len(line.strip()) == 0: continue if pattern in line.strip(): match_count += 1 #print(line.strip()) continue line = line.strip() if match_count == 1: if line == '};': # done with first enum break else: _arch, mnem, insn_id = extract_insn(line) # skip pseudo instructions if not mnem.startswith('__'): # PPC if mnem.endswith('-') or mnem.endswith('+'): mnem = mnem[:-1] if not first_insn: arch, first_insn = _arch, insn_id if not insn_id in insn_id_list: # save this insn_id_list[insn_id] = mnem if not mnem in mnem_list: print('\t"%s", // %s_INS_%s,' %(mnem.lower(), arch, mnem.upper())) mnem_list.append(mnem) #return arch, first_insn, insn_id_list return arch, first_insn, insn_id_list # GenAsmMatcher.inc #arch, first_insn, insn_id_list, match_lines = extract_matcher(sys.argv[1]) arch, first_insn, insn_id_list = extract_matcher(sys.argv[1])