1
# udis86 - scripts/ud_optable.py (optable.xml parser)
3
# Copyright (c) 2009 Vivek Thampi
6
# Redistribution and use in source and binary forms, with or without modification,
7
# are permitted provided that the following conditions are met:
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.
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.
28
from xml.dom import minidom
30
class UdOptableXmlParser:
32
def parseDef( self, node ):
37
for def_node in node.childNodes:
38
if not def_node.localName:
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 );
53
print "warning: invalid node - %s" % def_node.localName
55
return ( pfx, opc, opr, ven )
57
def parse( self, xml, fn ):
58
xmlDoc = minidom.parse( xml )
59
self.TlNode = xmlDoc.firstChild
61
while self.TlNode and self.TlNode.localName != "x86optable":
62
self.TlNode = self.TlNode.nextSibling
64
for insnNode in self.TlNode.childNodes:
65
if not insnNode.localName:
67
if insnNode.localName != "instruction":
68
print "warning: invalid insn node - %s" % insnNode.localName
71
mnemonic = insnNode.getElementsByTagName( 'mnemonic' )[ 0 ].firstChild.data
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 ) = \
80
if ( len( local_vendor ) ):
83
fn( prefixes, mnemonic, opcodes, operands, vendor )
86
def printFn( pfx, mnm, opc, opr, ven ):
89
print ' '.join( pfx ),
90
print "%s %s %s %s" % \
91
( mnm, ' '.join( opc ), ' '.join( opr ), ven )
94
def parse( xml, callback ):
95
parser = UdOptableXmlParser()
96
parser.parse( xml, callback )
99
parser = UdOptableXmlParser()
100
parser.parse( sys.argv[ 1 ], printFn )
102
if __name__ == "__main__":