1# udis86 - scripts/ud_optable.py (optable.xml parser) 2# 3# Copyright (c) 2009 Vivek Thampi 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without modification, 7# are permitted provided that the following conditions are met: 8# 9# * Redistributions of source code must retain the above copyright notice, 10# this list of conditions and the following disclaimer. 11# * Redistributions in binary form must reproduce the above copyright notice, 12# this list of conditions and the following disclaimer in the documentation 13# and/or other materials provided with the distribution. 14# 15# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 26import os 27import sys 28from xml.dom import minidom 29 30class UdOptableXmlParser: 31 32 def parseDef( self, node ): 33 ven = '' 34 pfx = [] 35 opc = [] 36 opr = [] 37 for def_node in node.childNodes: 38 if not def_node.localName: 39 continue 40 if def_node.localName == 'pfx': 41 pfx = def_node.firstChild.data.split(); 42 elif def_node.localName == 'opc': 43 opc = def_node.firstChild.data.split(); 44 elif def_node.localName == 'opr': 45 opr = def_node.firstChild.data.split(); 46 elif def_node.localName == 'mode': 47 pfx.extend( def_node.firstChild.data.split() ); 48 elif def_node.localName == 'syn': 49 pfx.extend( def_node.firstChild.data.split() ); 50 elif def_node.localName == 'vendor': 51 ven = ( def_node.firstChild.data ); 52 else: 53 print "warning: invalid node - %s" % def_node.localName 54 continue 55 return ( pfx, opc, opr, ven ) 56 57 def parse( self, xml, fn ): 58 xmlDoc = minidom.parse( xml ) 59 self.TlNode = xmlDoc.firstChild 60 61 while self.TlNode and self.TlNode.localName != "x86optable": 62 self.TlNode = self.TlNode.nextSibling 63 64 for insnNode in self.TlNode.childNodes: 65 if not insnNode.localName: 66 continue 67 if insnNode.localName != "instruction": 68 print "warning: invalid insn node - %s" % insnNode.localName 69 continue 70 71 mnemonic = insnNode.getElementsByTagName( 'mnemonic' )[ 0 ].firstChild.data 72 vendor = '' 73 74 for node in insnNode.childNodes: 75 if node.localName == 'vendor': 76 vendor = node.firstChild.data 77 elif node.localName == 'def': 78 ( prefixes, opcodes, operands, local_vendor ) = \ 79 self.parseDef( node ) 80 if ( len( local_vendor ) ): 81 vendor = local_vendor 82 # callback 83 fn( prefixes, mnemonic, opcodes, operands, vendor ) 84 85 86def printFn( pfx, mnm, opc, opr, ven ): 87 print 'def: ', 88 if len( pfx ): 89 print ' '.join( pfx ), 90 print "%s %s %s %s" % \ 91 ( mnm, ' '.join( opc ), ' '.join( opr ), ven ) 92 93 94def parse( xml, callback ): 95 parser = UdOptableXmlParser() 96 parser.parse( xml, callback ) 97 98def main(): 99 parser = UdOptableXmlParser() 100 parser.parse( sys.argv[ 1 ], printFn ) 101 102if __name__ == "__main__": 103 main() 104