This file is indexed.

/usr/share/pyshared/dissy/arm.py is in dissy 9-3.1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
######################################################################
##
## Copyright (C) 2006,  Blekinge Institute of Technology
##
## Author:        Simon Kagstrom <simon.kagstrom@gmail.com>
## Description:   Arm arch specific stuff
##
## Licensed under the terms of GNU General Public License version 2
## (or later, at your option). See COPYING file distributed with Dissy
## for full text of the license.
##
######################################################################
import sys, architecture
from dissy.architecture import Architecture

arm_jumps = ['b',
             'bcc',
             'bl',
             'ble',
             'bne',
             'bleq',
             'blt',
             'bgt',
             'beq',
             'bcs',
             ]
arm_calls = ['bl']
arm_conditionflag_setters = ['cmp'] + \
    [i + "s" for i in
    ['mul', 'mla', 'umull', 'umlal', 'smull',
    'smlal', 'mov', 'mvn', 'asr', 'lsl', 'lsr', 'ror', 'rrx',] #TODO more
    ]
arm_conditionflag_users = ['']

arm_instr_descriptions = {
    'cmp': 'Compare two values, and sets the condition flags',
    'adc': 'Add with carry',
    'add': 'Add',
    'sub': 'Subtract',
    'and': 'Logical and',
    'bic': 'Bit Clear',
    'bal': 'Unconditional Branch',
    'blal': 'Unconditional Branch and Link',
    'mov': 'Move',
    'mvn': 'Move and negate (XOR 0xFFFFFFFF)',
    'bx': """Branch and eXchange
PC := Rm""",
    'bl': """Branch with Link
LR := Address of next instruction, PC := label""",
    'push': """Push on the stack.
Canonical form of "stmdb SP!, <reglist>\"""",
    'pop': """Pop from the stack.
Canonical form of "ldm SP!, <reglist>\"""",
    'asr': 'Arithmetic Shift Right',
    'mul': 'Multiply',
    'muls': 'Multiply and set condition flags',
    'mla': 'Multiply and Accumulate',
    'mls': 'Multiply and Subtract',
    'smull': """Signed Multiply Long
%(arg1)s,%(arg2)s := signed(%(arg3)s * %(arg4)s)""",
    'ldr': 'Load (from memory to register)',
    'str': 'Store (from register to memory)',
    'lsl': 'Logical Shift Left',
    'lsls': 'Logical Shift Left and set condition flags',
    'lsr': 'Logical Shift Right',
    'lsr': 'Logical Shift Right and set condition flags',
    'rsb': 'Reverse Subtract',
}

arm_conditions = {
    'cs': 'Carry Set',
    'cc': 'Carry Clear',
    'eq': 'Equal (Zero Set)',
    'ne': 'Not Equal (Zero Clear)',
    'vs': 'Overflow Set',
    'vc': 'Overflow Clear',
    'gt': 'Signed Greater Than',
    'lt': 'Signed Less Than',
    'ge': 'Signed Greater than or Equal',
    'le': 'Signed Less than or Equal',
    'pl': 'Plus (Positive)',
    'mi': 'Minus (Negative)',
    'hi': 'Unsigned Higher Than',
    'lo': 'Unsigned Lower Than',
    'hs': 'Unsigned Higher or Same',
    'ls': 'Unsigned Lower or Same',
    }

arm_lists_inited = False
if not arm_lists_inited:
    conditional_instructions = {
        'b': """Branch on %s
PC := label, label is this instruction +/-32Mb""",
        'bx': """Branch and eXchange on %s
PC := Rm
Change to Thumb mode if Rm[0] is 1, change to ARM mode if Rm[0] is 0""",
        'bl': """Branch and Link on %s""",
        'mov': """Move on %s""",
        'add': """Add on %s""",
        'sub': """Subtract on %s""",
        }

    for i in conditional_instructions:
        for c in arm_conditions:
            arm_instr_descriptions[i + c] = conditional_instructions[i] % (arm_conditions[c])
            arm_conditionflag_users += [i + c]
    arm_lists_inited = True

class ArmArchitecture(architecture.Architecture):
    def __init__(self):
        architecture.Architecture.__init__(self, arm_jumps, arm_calls,
            arm_conditionflag_setters, arm_conditionflag_users)

    def getInstructionInfo(self, instruction):
        opcode = instruction.getOpcode()
        args = str(instruction.getArgs())

        args_list = args.split(", ")
        args_dict = dict(
            zip(['arg' + str(i) for i in range(1, len(args_list)+1)],
                args_list))
        description = arm_instr_descriptions.get(instruction.getOpcode(), '')

        return {'shortinfo': opcode + " " + args,
                'description': description % args_dict,
                }

    def parseArguments(self, instr):
        """Parses an argument string, into a two-tuple, containing:
            * A list of the registers read in this instruction
            * A list of the registers written to in this instruction"""

        def parseComSepList(lstr):
            ret = []
            tmp = ""
            stack = []
            for c in lstr:
                if c in "{[":
                    stack += [c]
                    tmp += c
                elif c in "]}":
                    tmp += c
                    c2 = stack.pop()
                    if c == "]" and c2 == "[" or \
                        c == "}" and c2 == "{":
                        ret += [tmp]
                        tmp = ""
                    else:
                        raise ValueError("unbalanced parenthesis")
                elif c == ' ':
                    pass
                elif stack == [] and c == ',':
                    ret += [tmp]
                    tmp = ""
                elif stack == []:
                    tmp += c
                else:
                    tmp += c
            if tmp:
                ret += [tmp]
            return ret
        def isRegister(s):
            if s in ['r' + str(i) for i in range(0, 16)]: #r0..r15
                return True
            if s in ['sl', #r10 = gcc "got pointer"?
                    'fp', #r11 = gcc frame pointer
                    'ip', #r12 = gcc "scratch register"?
                    'sp', #r13, stack pointer
                    'lr', #r14, link register
                    'pc']: #r15, program counter
                return True
            return False
        def isValue(s):
            if s[:1] == '#':
	        if s[1:].isdigit():
                    return True
            return False
        regwrite = []
        regread = []
        values = []
        args = parseComSepList(instr.args)
        values = [int(a[1:]) for a in args if isValue(a)]

        if instr.getOpcode()[:3] == 'cmp':            
            regread = [a for a in args if isRegister(a)]
        elif instr.getOpcode()[:3] in ['sub', 'add', 'lsl', 'asr', 'rsb', 'mov', 'and', 'mvn']:
            regwrite = [args[0]]
            regread = [a for a in args[1:] if isRegister(a)]
        #branches
        elif instr.getOpcode() in ['b' + c for c in arm_conditions.keys() + ['']]:
            regwrite = ['pc']
        elif instr.getOpcode() in ['bl' + c for c in arm_conditions.keys() + ['']]:
            regwrite = ['pc', 'lr']
        elif instr.getOpcode() in ['bx' + c for c in arm_conditions.keys() + ['']]:
            regwrite = ['pc']
            regread = [args[0]]
        elif instr.getOpcode() in ['blx' + c for c in arm_conditions.keys() + ['']]:
            regwrite = ['pc']
            regread = isRegister(args[0]) and [args[0]] or []
        #load
        elif instr.getOpcode() in ['ldr' + c for c in arm_conditions.keys() + ['']]:
            regwrite = [args[0]]
            if args[1].startswith('['):
                offsetl = parseComSepList(args[1][1:-1])
                regread = [r for r in offsetl if isRegister(r)]
        #store
        elif instr.getOpcode() in ['str' + c for c in arm_conditions.keys() + ['']]:
            regread = [args[0]]
            if args[1].startswith('['):
                offsetl = parseComSepList(args[1][1:-1])
                regread += [r for r in offsetl if isRegister(r)]
        #push
        elif instr.getOpcode() in ['push' + c for c in arm_conditions.keys() + ['']]:
            regwrite = ['sp']
            regread = ['sp']
            reglist = parseComSepList(args[0][1:-1])
            regread += reglist
        elif instr.getOpcode() in ['pop' + c for c in arm_conditions.keys() + ['']]:
            regwrite = ['sp']
            regread = ['sp']
            reglist = parseComSepList(args[0][1:-1])
            regwrite += reglist
        elif instr.getOpcode() in ['smull' + c for c in arm_conditions.keys() + ['']]:
            regwrite = [args[0], args[1]]
            regread = [args[2], args[3]]
        elif instr.getOpcode() in ['mla' + c for c in arm_conditions.keys() + ['']]:
            regwrite = [args[0]]
            regread = args[1:]
        elif instr.getOpcode() in ['mul' + c for c in arm_conditions.keys() + ['']] + \
        ['muls' + c for c in arm_conditions.keys() + ['']]:
            regwrite = [args[0]]
            regread = [args[1], args[2]]
        elif instr.getOpcode() == '.word':
            return ([], [], [])
        else:
            raise ValueError("Unknown instruction opcode: " + str(instr))

        return (regread, regwrite, values)