~ubuntu-branches/debian/sid/upx-ucl/sid

« back to all changes in this revision

Viewing changes to src/stub/src/arch/i086/cleanasm.py

  • Committer: Bazaar Package Importer
  • Author(s): Robert Luberda
  • Date: 2009-09-20 21:34:57 UTC
  • mfrom: (1.2.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20090920213457-x95n0rq823lx12sw
Tags: 3.03-3
* Upload to unstable.
* Standards-Version: 3.8.3 (no changes).
* Build with debhelper v7.
* rules: call dh_prep instead of `dh_clean -k'.

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
#
6
6
#  This file is part of the UPX executable compressor.
7
7
#
8
 
#  Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
 
8
#  Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer
9
9
#  All Rights Reserved.
10
10
#
11
11
#  UPX and the UCL library are free software; you can redistribute them
24
24
#  59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25
25
#
26
26
#  Markus F.X.J. Oberhumer              Laszlo Molnar
27
 
#  <mfx@users.sourceforge.net>          <ml1050@users.sourceforge.net>
 
27
#  <markus@oberhumer.com>               <ml1050@users.sourceforge.net>
28
28
#
29
29
 
30
30
 
38
38
    auto_inline = 1
39
39
    call_rewrite = 1
40
40
    loop_rewrite = 1
 
41
    mov_rewrite = 1
41
42
 
42
43
 
43
44
inline_map = {
76
77
    lines = filter(None, map(string.rstrip, lines))
77
78
    #
78
79
    #
 
80
    def inst_has_label(inst):
 
81
        return inst in [
 
82
            "call", "ja", "jae", "jb", "jbe", "jcxz", "je",
 
83
            "jg", "jge", "jl", "jle", "jmp", "jne", "loop",
 
84
        ]
79
85
    labels = {}
80
86
    def parse_label(inst, args):
81
87
        k = v = None
114
120
        def match(a, b):
115
121
            if b is None:
116
122
                return False
117
 
            if "^" in a or "*" in a:
 
123
            if "^" in a or "*" in a or "$" in a:
118
124
                # regexp
119
125
                return re.search(a, b.lower())
120
126
            else:
174
180
        label = m.group(1).strip()
175
181
        inst = m.group(2).strip()
176
182
        args = ""
177
 
        if m.group(3): args = m.group(3).strip()
 
183
        if m.group(3):
 
184
            args = m.group(3).strip()
 
185
        if not inst_has_label(inst):
 
186
            def hex2int(m): return str(int(m.group(0), 16))
 
187
            args = re.sub(r"\b0x[0-9a-fA-F]+\b", hex2int, args)
178
188
        #
179
 
        if inst in ["movl",] and re.search(r"\b[de]s\b", args):
180
 
            # fix bug in objdump
181
 
            inst = "movw"
182
 
        m = re.search(r"^(.+?)\b0x0\s+(\w+):\s+(1|2|R_386_16|R_386_PC16)\s+(__\w+)$", args)
 
189
        if 1 and inst in ["movl",] and re.search(r"\b[de]s\b", args):
 
190
            # work around a bug in objdump 2.17 (fixed in binutils 2.18)
 
191
            inst = "mov"
 
192
        m = re.search(r"^(.+?)\b(0|0x0)\s+(\w+):\s+(1|2|R_386_16|R_386_PC16)\s+(__\w+)$", args)
183
193
        if m:
184
194
            # 1 or 2 byte reloc
185
 
            args = m.group(1) + m.group(4)
 
195
            args = m.group(1) + m.group(5)
186
196
        olines.append([label, inst, args, None])
187
197
    #
188
198
    # pass 2
199
209
                    s = [
200
210
                        ["push", "word ptr [bp+8]"],
201
211
                        ["push", "word ptr [bp+6]"],
202
 
                        ["push", r"word ptr \[bp([+-]\d+)\]$"],
203
 
                        ["push", r"word ptr \[bp([+-]\d+)\]$"],
 
212
                        ["push", r"word ptr \[bp([+-](\d+))\]$"],
 
213
                        ["push", r"word ptr \[bp([+-](\d+))\]$"],
204
214
                    ]
205
215
                    dpos = omatch(i-1, -4, s)
206
216
                    if dpos:
208
218
                        continue
209
219
                if k in ["__LMUL", "__U4M",]:
210
220
                    s1 = [
211
 
                        ["mov",  "bx,0x300"],
 
221
                        ["mov",  "bx,768"],     # 0x300
212
222
                        ["xor",  "cx,cx"],
213
223
                    ]
214
224
                    s2 = [
234
244
                        continue
235
245
                if k == "__PIA":
236
246
                    s = [
237
 
                        ["mov",  "bx,0x1"],
 
247
                        ["mov",  "bx,1"],
238
248
                        ["xor",  "cx,cx"],
239
249
                    ]
240
250
                    dpos = omatch(i-1, -2, s)
253
263
                        continue
254
264
        if opts.loop_rewrite and inst in ["loop"]:
255
265
            s = [
256
 
                ["mov",  r"^c[lx],0xb$"],
 
266
                ["mov",  r"^c[lx],11$"],
257
267
                ["shr",  "dx,1"],
258
268
                ["rcr",  "ax,1"],
259
269
            ]
262
272
                orewrite_inst(i, "M_shrd_11", "", dpos)
263
273
                continue
264
274
            s = [
265
 
                ["mov",  r"^c[lx],0x8$"],
 
275
                ["mov",  r"^c[lx],8$"],
266
276
                ["shl",  "ax,1"],
267
277
                ["rcl",  "dx,1"],
268
278
            ]
271
281
                orewrite_inst(i, "M_shld_8", "", dpos)
272
282
                continue
273
283
            s1 = [
274
 
                ["mov",  r"^c[lx],0x8$"],
 
284
                ["mov",  r"^c[lx],8$"],
275
285
                ["shl",  "si,1"],
276
286
                ["rcl",  "di,1"],
277
287
            ]
278
288
            s2 = [
279
 
                ["les",  r"^bx,dword ptr \[bp([+-]\d+)\]$"],
 
289
                ["les",  r"^bx,dword ptr \[bp([+-](\d+))\]$"],
280
290
            ]
281
291
            dpos1 = omatch(i-1, -3, s1)
282
292
            dpos2 = omatch(i+1,  1, s2)
286
296
                continue
287
297
            s1 = [
288
298
                ["mov",  "ax,si"],
289
 
                ["mov",  r"^c[lx],0x8$"],
 
299
                ["mov",  r"^c[lx],8$"],
290
300
                ["shl",  "ax,1"],
291
301
                ["rcl",  "di,1"],
292
302
            ]
293
303
            s2 = [
294
304
                ["mov",  "si,ax"],
295
 
                ["les",  r"^bx,dword ptr \[bp([+-]\d+)\]$"],
 
305
                ["les",  r"^bx,dword ptr \[bp([+-](\d+))\]$"],
296
306
            ]
297
307
            dpos1 = omatch(i-1, -4, s1)
298
308
            dpos2 = omatch(i+1,  2, s2)
301
311
                orewrite_inst(i, "M_shld_diax_8_bxcx", "", dpos1[-3:])
302
312
                continue
303
313
            s1 = [
304
 
                ["mov",  r"^c[lx],0x8$"],
305
 
                ["shl",  r"^word ptr \[bp([+-]\d+)\],1$"],
306
 
                ["rcl",  r"^word ptr \[bp([+-]\d+)\],1$"],
 
314
                ["mov",  r"^c[lx],8$"],
 
315
                ["shl",  r"^word ptr \[bp([+-](\d+))\],1$"],
 
316
                ["rcl",  r"^word ptr \[bp([+-](\d+))\],1$"],
307
317
            ]
308
318
            s2 = [
309
319
                ["mov",  r"^dx,word ptr"],
322
332
                orewrite_inst(i, m, "", dpos1)
323
333
                continue
324
334
            s1 = [
325
 
                ["mov",  r"^word ptr \[bp([+-]\d+)\],si$"],
326
 
                ["mov",  r"^word ptr \[bp([+-]\d+)\],di$"],
327
 
                ["mov",  r"^c[lx],0xb$"],
328
 
                ["shr",  r"^word ptr \[bp([+-]\d+)\],1$"],
329
 
                ["rcr",  r"^word ptr \[bp([+-]\d+)\],1$"],
 
335
                ["mov",  r"^word ptr \[bp([+-](\d+))\],si$"],
 
336
                ["mov",  r"^word ptr \[bp([+-](\d+))\],di$"],
 
337
                ["mov",  r"^c[lx],11$"],
 
338
                ["shr",  r"^word ptr \[bp([+-](\d+))\],1$"],
 
339
                ["rcr",  r"^word ptr \[bp([+-](\d+))\],1$"],
330
340
            ]
331
341
            s2 = [
332
342
                ["mov",  r"^bx,word ptr"],
333
343
                ["mov",  r"^bx,word ptr"],
334
 
                ["mov",  r"^ax,word ptr \[bp([+-]\d+)\]$"],
335
 
                ["mov",  r"^dx,word ptr \[bp([+-]\d+)\]$"],
 
344
                ["mov",  r"^ax,word ptr \[bp([+-](\d+))\]$"],
 
345
                ["mov",  r"^dx,word ptr \[bp([+-](\d+))\]$"],
336
346
            ]
337
347
            dpos1 = omatch(i-1, -5, s1)
338
348
            dpos2 = omatch(i+1,  4, s2)
346
356
                m = "M_shrd_11_disi_bp %s %s" % (bp_dx, bp_ax)
347
357
                orewrite_inst(i, m, "", dpos1 + dpos2[-2:])
348
358
                continue
 
359
        if opts.mov_rewrite and inst in ["mov"]:
 
360
            s = [
 
361
                ["mov",  r"^al,byte ptr \[(di|si)\]$"],
 
362
                ["xor",  r"^ah,ah$"],
 
363
                ["mov",  r"^word ptr \[bp([+-](\d+))\],ax$"],
 
364
                ["mov",  r"^word ptr \[bp([+-](\d+))\],(0|1)$"],
 
365
                ["mov",  r"^word ptr \[bp([+-](\d+))\],(0|1)$"],
 
366
                ["mov",  r"^word ptr \[bp([+-](\d+))\],(0|1)$"],
 
367
                ["mov",  r"^word ptr \[bp([+-](\d+))\],(0|1)$"],
 
368
                ["mov",  r"^word ptr \[bp([+-](\d+))\],(0|1)$"],
 
369
                ["mov",  r"^word ptr \[bp([+-](\d+))\],(0|1)$"],
 
370
                ["mov",  r"^word ptr \[bp([+-](\d+))\],(0|1)$"],
 
371
                ["mov",  r"^word ptr \[bp([+-](\d+))\],(0|1)$"],
 
372
                ["mov",  r"^word ptr \[bp([+-](\d+))\],(0|1)$"],
 
373
                ["mov",  r"^bx,word ptr \[bp([+-](\d+))\]$"],
 
374
                ["mov",  r"^word ptr \[bx\],(0)$"],
 
375
                ["mov",  r"^word ptr \[bx([+-](\d+))\],(0)$"],
 
376
                ["mov",  r"^bx,word ptr \[bp([+-](\d+))\]$"],
 
377
                ["mov",  r"^word ptr \[bx\],(0)$"],
 
378
                ["mov",  r"^word ptr \[bx([+-](\d+))\],(0)$"],
 
379
                ["mov",  r"^dl,byte ptr \[(di|si)([+-](\d+))\]$"],
 
380
                ["xor",  r"^dh,dh$"],
 
381
                ["mov",  r"^cx,ax$"],
 
382
            ]
 
383
            dpos = omatch(i, -len(s), s)
 
384
            if dpos:
 
385
                ipos, n_del = 16, 0
 
386
                pos0 = dpos[0][0]
 
387
                r = []
 
388
                for pos, m0, m1 in dpos:
 
389
                    assert pos == pos0 + len(r)
 
390
                    r.append([olines[pos][1], olines[pos][2]])
 
391
                z0 = r[0]; z1 = r[2]; del r[:3]
 
392
                r.insert(0, ["xor", "ax,ax"])
 
393
                r.insert(ipos, z0); r.insert(ipos + 1, z1)
 
394
                i = 0
 
395
                while i < len(r):
 
396
                    inst, args = r[i]
 
397
                    if inst == "mov" and args.endswith(",0"):
 
398
                        r[i] = [inst, args[:-1] + "ax"]
 
399
                    elif inst == "mov" and args.endswith(",1"):
 
400
                        assert i < ipos
 
401
                        r.insert(ipos, [inst, args[:-1] + "ax"])
 
402
                        del r[i]; i -= 1; n_del += 1
 
403
                    i += 1
 
404
                assert len(r) == len(dpos)
 
405
                pos = pos0
 
406
                for inst, args in r:
 
407
                    ##print pos-pos0, inst, args
 
408
                    olines[pos][1] = inst
 
409
                    olines[pos][2] = args
 
410
                    pos += 1
 
411
                if n_del:
 
412
                    olines.insert(pos0 + ipos - n_del, [None, "inc", "ax", None])
 
413
                continue
349
414
        #
350
 
        if inst in [
351
 
            "call", "ja", "jae", "jb", "jbe", "jcxz", "je",
352
 
            "jg", "jge", "jl", "jle", "jmp", "jne", "loop",
353
 
        ]:
 
415
        if inst_has_label(inst):
354
416
            k, v = parse_label(inst, args)
355
417
            olines[i][2] = None
356
418
            olines[i][3] = add_label(k, v)
385
447
    #
386
448
    # write ofile
387
449
    ofp = open(ofile, "wb")
 
450
    current_label = None
388
451
    for label, inst, args, args_label in olines:
389
452
        if labels.has_key(label):
 
453
            current_label = labels[label][2]
390
454
            if opts.verbose:
391
455
                ofp.write("%s: /* %d */\n" % (labels[label][2], labels[label][3]))
392
456
            else:
393
457
                ofp.write("%s:\n" % (labels[label][2]))
394
458
        if inst == "*DEL*":
395
459
            continue
 
460
        if 1 and current_label in [".Lf122", ".Lf123", ".Lf124", ".Ls122", ".Ls123", ".Ls124"]:
 
461
            continue
396
462
        if args_label:
397
463
            if opts.verbose:
398
464
                args = "%s /* %d */" % (labels[args_label][2], labels[args_label][3])
399
465
            else:
400
466
                args = labels[args_label][2]
 
467
        if 0:
 
468
            # remove unneeded "byte/word/dword ptr"
 
469
            # [this works, but disabled for now as we gain nothing]
 
470
            if re.search(r"\bbyte ptr ", args):
 
471
                if re.search(r"^[abcd][hl],", args): args = args.replace("byte ptr ", "")
 
472
                if re.search(r",[abcd][hl]$", args): args = args.replace("byte ptr ", "")
 
473
            if re.search(r"\bword ptr ", args):
 
474
                if re.search(r"^[abcds][ix],", args): args = args.replace("word ptr ", "")
 
475
                if re.search(r",[abcds][ix]$", args): args = args.replace("word ptr ", "")
 
476
            if re.search(r"\bdword ptr ", args):
 
477
                if re.search(r"^[abcd][x],",  args): args = args.replace("dword ptr ", "")
401
478
        l = "%8s%-7s %s" % ("", inst, args)
402
479
        ofp.write(l.rstrip() + "\n")
403
480
    ofp.close()