wok view linld/stuff/src/pipehole.awk @ rev 24334

polkit: CVE-2021-4034
author Pascal Bellard <pascal.bellard@slitaz.org>
date Fri Jan 28 11:07:11 2022 +0000 (2022-01-28)
parents 6b6d14c9f7e9
children c11594098e34
line source
1 BEGIN { hold=0; is386=0; isload=0; isiso=0; istazboot=0; wascall=0; ishimem=0; label="none"; xlabel=""; file="" }
2 function isnum(n) { return match(n,/^[0-9+-]/) }
3 {
4 sub(/segment word public/,"segment byte public")
6 if (/^ ; $/) next
7 if (/^@.*:$/ || / endp$/) afterjmp=0
8 if (/^ \.386p$/) is386=1
9 if (file == "" && /debug S/) { file=$3; gsub(/\"/,"",file) }
10 if (/debug S/) {
11 print " %PAGESIZE 255"
12 print " include common.inc"
13 }
14 if (file == "linld.cpp") {
15 if (/\[si/ || /si,/ || /,si/) sub(/si/,"di")
16 else if (/\[di/ || /di,/ || /,di/) sub(/di/,"si")
17 if (/add di,2/) $0=" scasw ; " $0
18 if (/bx,di/ || /\[bp-2\]/) next
19 sub(/\[bx\],0/,"[di],0")
20 if (/ptr @exit\$qv/) {
21 if (gotexit) next
22 print "call_exit:"
23 gotexit=1
24 }
25 if (/short @1@422/ && gotexit) $0=" ja call_exit"
26 if (islinld==1) {
27 if (/,word.*/) islinld=0
28 print "; " $0
29 next
30 }
31 if (/^_main proc/) islinld=1
32 if (/image\|initrd/) islinld=3
33 if (islinld==3 && /bx,word ptr/) { print "; " $0; next }
34 if (/fileexist\$qpxzc/) islinld=4
35 if (islinld==4) {
36 if (/DGROUP:_heap_top/) next
37 if (/ax,-1/) {
38 print " inc ax"
39 print " mov ax,word ptr [di]"
40 next
41 }
42 if (/ax,word ptr \[/) next
43 }
44 if (/buf_cmdline\+1/) {
45 islinld=5
46 print " mov bx,offset DGROUP:_buf_cmdline+1"
47 sub(/offset DGROUP:_buf_cmdline\+1/,"bx")
48 }
49 if (islinld==5) {
50 if (/bx,offset DGROUP:_buf_cmdline/) $0=" dec bx"
51 if (/ax,word ptr/) next
52 if (/call/) islinld=0
53 }
54 if (/bx,word ptr DGROUP:_cmdstr\+6/) next
55 if (/_cmdstr\+6,0/) {
56 print " mov bx,word ptr [si+6]"
57 $0=" or bx,bx"
58 }
59 if (/heap_top \+1;/) islinld=6
60 if (islinld==6) {
61 sub(/ax/,"bx")
62 if (/strcatb/) {
63 print " dec bx"
64 islinld=4
65 }
66 }
67 } # file == "linld.cpp"
68 if (file == "himem.cpp") {
69 if (/sp,bp/ || /pop bp/ || /enter/ || /leave/) next
70 if (/void load_image/) ishimem=1
71 if (ishimem == 1 && is386 == 0) {
72 if (/si\+8\]$/ || /si\+4\]$/ || /si\+16\]$/) next
73 if (/si\+6\]$/ || /si\+2\]$/ || /si\+14\]$/) sub(/mov dx,/,"les dx,d")
74 if (/si\+12\],ax/ || /si\+16\],ax/ || /di\+2\],ax/ || /DGROUP:_himem_buf\+2,ax/) sub(/,ax/,",es")
75 if (/dx,dword ptr \[si\+14\]/ || /DGROUP:_himem_buf,dx/) sub(/dx/,"ax")
76 }
77 if (ishimem == 1) {
78 if (/do \{/) ishimem=2
79 if (/bx,si/ || /di,ax/ || /push bp/ || /bp,sp/ || /push di/ || /push si/) next
80 if (/sp,2/ || /bp\+4/) next
81 }
82 if (ishimem == 2) {
83 if (/movzx/) print " cwde"
84 if (/bp-2/ || /di,ax/ || /bx,di/ || /bx,si/) next
85 if (/storepage.bufv/) {
86 print " inc ax"
87 print " push ax"
88 }
89 if (/buf \+= size;/) {
90 print " pop ax"
91 }
92 if (/i\+12/) ishimem=20
93 }
94 if (ishimem == 20) {
95 if (/loadfail/) next
96 if (/je/) {
97 print " extrn jmploadfailure"
98 $0=" jne short jmploadfailure"
99 }
100 if (/endp/) ishimem=0
101 }
102 if (/@memcpy_image\$qp11image_himem/) next
103 if (/far last_ditch/) ishimem=3
104 if (ishimem == 3) {
105 sub(/DGROUP:_imgs\+4,/,"[si+4],")
106 if (/bx,di/ || /di,ax/) next
107 }
108 } # file == "himem.cpp"
109 if (file == "load.cpp") {
110 if (isload != 3 && isload != 6) { # LOAD.LST
111 if (/,si/ || /si,/ || /\[si/) sub(/si/,"di")
112 else if (/,di/ || /di,/ || /\[di/) sub(/di/,"si")
113 }
114 if (/moverm\(/) isload=16
115 if (isload != 16 && /bx,si/) next
116 if (/@moverm/) isload=0
117 if (/readrm\(m, 0x200/) isload=15
118 if (isload == 15) { # LOAD.LST
119 if (/bx,si/) next
120 if (/call/) isload=0
121 }
122 if (/load_image\(/) {
123 if (isload == 3) isload=13
124 else isload=14
125 }
126 if (isload == 14) { # LOAD.LST
127 if (/call/) $0=" jmp short load_imagez"
128 if (/ret/) isload=0
129 if (/pop/ || /ret/ || /push/) next
130 }
131 if (isload == 13) { # LOAD.LST
132 if (/pop/) isload=3
133 if (/push/ || /call/ || /pop/) next
134 }
135 if (/i\+21\],513$/) isload=11
136 if (isload == 12) { # LOAD.LST
137 if (/cmp/) next
138 if (/jb/) isload=0
139 sub(/jb/,"jcxz")
140 }
141 if (isload == 11) { # LOAD.LST
142 if (/cmp/) {
143 print " mov cx,513"
144 sub(/cmp /,"sub cx,")
145 sub(/,513/,"")
146 }
147 if (/jb/) isload=12
148 sub(/jb/,"ja")
149 }
150 sub(/_imgs\+65534/,"_imgs-2")
151 if (/setup_sects == 0/) isload=9
152 if (isload == 9) { # LOAD.LST
153 sub(/,0/,",al ; worst case 2k boundary (iso)")
154 if (/jne/) isload=0
155 }
156 if (/cmd_line_ptr =/ && is386 == 0) isload=7
157 if (isload == 7) { # LOAD.LST
158 if (/add/ || /xor/ || /extrn/ || /N_LXLSH@/ || /cl,4/ || /,ax/) next
159 if (/enable A20 if needed/) { print nextinst; isload=0 }
160 if (/i-463/) $0=" mov bx,-463"
161 if (/i-465/) {
162 sub(/465/,"2"); sub(/\[/,"[bx+")
163 nextinst=$0; sub(/-2\],-23745/,"],8000h",nextinst)
164 }
165 if (/,dx/) {
166 print " mov cl,12"
167 print " shr ax,cl"
168 print " mov bx,55"
169 sub(/dx/,"ax")
170 }
171 }
172 if (/pm_low == 0/) {
173 print " push di"
174 print " push si"
175 isload=6
176 }
177 if (isload == 6) { # LOAD.LST
178 if (/si\+2/) {
179 print " cmpsw"
180 next
181 }
182 if (/les/) sub(/bx,/,"di,")
183 if (/bx\+4/ || /es:/ || /call/ || /pop/ || /ret/) next
184 if (/si\+6/) {
185 print " movsw"
186 print " movsw"
187 print " movsw"
188 print " movsw"
189 print " pop si"
190 print "load_imagez:"
191 next
192 }
193 }
194 if (isload == 5) { # LOAD.LST
195 sub(/ax,/,"bx,")
196 if (/@puts\$qpxzc/) isload=0
197 if (/mov bx,ax/) next
198 sub(/,word ptr \[di\+29\]/,",cx")
199 }
200 if (/_cmdnum\+14/ && is386 == 0) isload=4
201 if (isload == 4) { # LOAD.LST
202 if (/_cmdnum\+14/) next
203 if (/_cmdnum\+12$/) {
204 $0=" les dx,dword ptr [bx+12]"
205 }
206 sub(/,ax/,",es")
207 if (/add ax,word ptr/) $0=" add ax,cx"
208 if (/i\+29\],0/) {
209 sub(/,0$/,"")
210 sub(/cmp /,"mov cx,")
211 }
212 sub(/je/,"jcxz")
213 if (/@strcpy/) isload=0
214 if (/\+0x200/) isload=5
215 }
216 if (/void load_initrd\(\)/) { isload=3; isload2=0 }
217 if (isload == 3) { # LOAD.LST
218 if (/bx,offset DGROUP:_imgs\+28/ || /push si/) next
219 if (/si,offset DGROUP:_imgs\+28/) print " push si"
220 if (/cmdstr\+4,0/) {
221 isload2++
222 print " mov ax,word ptr DGROUP:_cmdstr+4"
223 $0=" or ax,ax"
224 }
225 if (isload2 && /DGROUP:_cmdstr\+4/) $0=";" $0
226 if (/je short @2@.*/) sub(/@2@.*/,"load_initrd_ret")
227 if (/mov ax,word ptr \[si\]/) $0=" lodsw"
228 if( /jmp/) {
229 print "load_initrd_ret:"
230 print " ret"
231 next
232 }
233 if (/@loadfailure/) {
234 print " global jmploadfailure:near"
235 print "jmploadfailure:"
236 }
237 sub(/\[di/,"[bx")
238 sub(/di,/,"bx,")
239 }
240 if (/mode = vid_mode/) { isload=2; print " mov bx,offset _cmdnum" }
241 if (isload == 2) { # LOAD.LST
242 if (/DGROUP:_cmdnum/) { sub(/DGROUP:_cmdnum/,"[bx"); $0=$0 "]"}
243 sub(/,0/,""); sub(/cmp /,"mov cx,")
244 sub(/je/,"jcxz")
245 if (/ax,word/) next
246 sub(/,ax/,",cx")
247 if (/starting linux 1\.3\.73/) isload=0
248 }
249 if (/_rm_size=0x200/ || /heap_top = _rm_buf/) isload=1
250 if (isload == 1) { # LOAD.LST
251 if (/ptr .die\$qpxzc/) $0="@die@:\n" $0
252 if (/mov al,byte ptr/ && is386) {
253 sub(/mov al/,"movzx eax")
254 }
255 if (is386 == 0) {
256 if (/m->size -= _rm_size/) print " cwd ; do not trust rewind result (iso case)"
257 sub(/,0$/,",dx")
258 }
259 if (/ax,word ptr/) next
260 if (/^ call/) isload=0
261 }
262 } # file == "load.cpp"
263 if (file == "iso9660.cpp") {
264 if (swapsidi == 1) {
265 if (/\[si/) sub(/\[si/,"[di")
266 else (/\[di/) sub(/\[di/,"[si")
267 if (/\+si/) sub(/\+si/,"+di")
268 else (/\+di/) sub(/\+di/,"+si")
269 if (/,si/) sub(/,si/,",di")
270 else if (/,di/) sub(/,di/,",si")
271 if (/si,/) sub(/si,/,"di,")
272 else if (/di,/) sub(/di,/,"si,")
273 }
274 if (/di,offset DGROUP:_buf2k/) { si="si"; di="di" }
275 if (/si,offset DGROUP:_buf2k/) { si="di"; di="si" }
276 if (/leave/ || /enter/ || /bp/ || /sub sp,/) next
277 if (/ptr \[.i\+8\],dx/) next
278 if (/ptr \[.i\+6\],ax/) next
279 if (/ptr \[.i\+6\],eax/) next
280 if (/x,word ptr \[.i\+32\]/) next
281 if (/add word ptr \[.i\],ax/) sub(/ax/,"cx")
282 if (/ax,word ptr \[si\+18\]/) sub(/mov ax,/,"les ax,d")
283 if (/ax,word ptr \[si\+20\]/) next
284 if (/word ptr \[si\+25\],ax/) sub(/ax/,"es")
285 sub(/di,word ptr DGROUP:_isostate\+2/,"di,word ptr [si+2]")
286 if (/-257/) isiso=22
287 if (isiso == 22) {
288 sub(/-257/,"-257 ; clear C")
289 if (/je/) {
290 print " cbw"
291 print " xchg ax,bx"
292 print " xchg ax,dx ; .. or ."
293 $0=" je returnC"
294 }
295 }
296 if (/p = buf2k \+ 32 \+ x->curpos/) isiso=21
297 if (isiso == 21) { # ISO9660.LST
298 if (/ax,/) next
299 if (/.i,ax/) sub(/mov/,"xchg")
300 if (/# else/) isiso=0
301 }
302 if (/cx,.i/) {
303 if (isiso == 0) {
304 print " ifndef CLEAN_ISO9660"
305 print " inc " di
306 print " mov cx," di
307 }
308 isiso=20
309 }
310 if (isiso == 20) { # ISO9660.LST
311 if (/bx,dx/) {
312 isiso=12
313 next
314 }
315 if (/add .i,ax/ || /cbw/) next
316 if (/cmp/) sub(/\[/,"[bx+")
317 if (/inc cx/) next
318 if (/sub/) sub(/.i/,"bx")
319 sub(/inc .i/,"inc bx")
320 if (/al,byte ptr/) {
321 next
322 }
323 sub(/i-1\],12603/,"i],12603")
324 if (/bx\+.i\],46/) {
325 print " inc " di
326 print " mov cx," di
327 }
328 if (/i],0/) {
329 print " ifndef CLEAN_ISO9660"
330 print " inc " di
331 print " mov cx," di
332 print " endif"
333 print "seteos:"
334 sub(/,0/,",bh ; clear C")
335 sub(/mov byte ptr \[/,"and byte ptr [bx+")
336 }
337 if (/cx,.i/) next
338 if (/\}/) {
339 print " xchg ax,cx"
340 }
341 if (/cx,5/) $0=" lea dx,[" di "+5]"
342 if (/filename = s;/) {
343 isiso=0
344 }
345 }
346 if (isiso == 19) { # ISO9660.LST
347 if (/short @2@310/) $0=" jc restoreC"
348 if (/si\+32/ || /ax,dx/ || /ax,di/ || /cmp ax,-1/ || /sub ax,/) next
349 if (/ax,word ptr \[si\+28\]/) next
350 if (/bx,offset/) sub(/bx/,"ax")
351 sub(/dx,/,"bx,")
352 if (/short @2@282/) sub(/je/,"jnc")
353 if (/\[si\+30\],0/) $0=" ;or cl,cl"
354 if (/short @2@478/) sub(/je/,"jcxz")
355 if (/@strcmp\$qpxzct1/) {
356 print
357 print "restoreC:"
358 $0=" mov byte ptr [di],dl ; c"
359 isiso=1
360 }
361 }
362 if (isiso == 18) { # ISO9660.LST
363 if (/endif/) isiso=1
364 }
365 if (isiso == 17) { # ISO9660.LST
366 if (/si\+18/) {
367 print "next:"
368 print " mov word ptr [si+20],bx"
369 print
370 isiso=0
371 }
372 if (/_buf2k\+167/) {
373 print
374 $0=""
375 }
376 else sub(/ax/,"bx")
377 if (/,bx/) next
378 if (/isoreadrootsector/) {
379 print
380 print " mov ax,word ptr [_buf2k+1]"
381 print " xor ax,17475 ; clear C, CD"
382 print "jne_returnNotC:"
383 print " cmc"
384 $0=" jne returnC"
385 }
386 }
387 if (/if \(c\)/) isiso=16
388 if (isiso == 16) { # ISO9660.LST
389 if (/cmp/) {
390 print " mov bx,word ptr [si+7]"
391 print " mov ax,word ptr [si+11]"
392 print " dec dx"
393 print " jns next"
394 }
395 if (/isolseek/) isiso=1
396 else if (! /;/) next
397 }
398 if (/found:/) isiso=15
399 if (isiso != 15 && /si,offset DGROUP:_isostate/) $0=";" $0
400 if (isiso == 15) { # ISO9660.LST
401 if (/xor/) {
402 print "returnC:"
403 print " sbb dx,dx"
404 print "return:"
405 next
406 }
407 if (/i\+28\],cx/) {
408 print " ifndef BASIC_ISO9660"
409 print " xchg ax,dx"
410 print " endif"
411 next
412 }
413 if (/@1@422:/) next
414 if (/\[di\],47/) isiso=17
415 }
416 if (isiso == 14) { # ISO9660.LST
417 if (/ax,/ || /jge/) next
418 sub(/mov/,"sub")
419 sub(/,ax/,",8")
420 if (/jmp/) {
421 print " ;JUMPS"
422 print " jb returnCXZC"
423 $0=" ;NOJUMPS"
424 isiso=0
425 }
426 }
427 if (/p = buf2k \+ 34/) isiso=13
428 if (isiso == 13) { # ISO9660.LST
429 #if (/cbw/) $0=" ;cbw"
430 if (/i,.i/) $0=" xchg ax,bx"
431 if (/i,ax/) $0=" xchg ax," di
432 if (/i,70/ || /ptr \[.i\+32\]/) next
433 if (/register len/) {
434 isiso=12
435 }
436 }
437 if (isiso == 12) { # ISO9660.LST
438 if (/.i\+2/) sub(/al/,"bl")
439 if (/cbw/) next
440 if (/dx,ax/) next
441 if (/bx,dx/) next
442 sub(/i,dx/,"i,bx")
443 sub(/cx,/,"dx,")
444 if (/bx\+.i\],0/) {
445 sub(/,0/,",bh")
446 }
447 if (/jmp/) {
448 print
449 $0=" endif"
450 }
451 if (/jne/) {
452 print " ifdef BASIC_ISO9660"
453 print " lea cx,[" di "+5]"
454 print " je seteos"
455 print " else"
456 }
457 if (/while/) isiso=120
458 }
459 if (isiso == 120) { # ISO9660.LST
460 sub(/ax/,"cx")
461 if (/cmp cx,/) $0=" cmp " di ",cx"
462 sub(/jae/,"jb")
463 if (/endif/) isiso=0
464 }
465 if (/curpos >= SECT/) isiso=10
466 if (isiso == 10) { # ISO9660.LST
467 if (/,2048/) {
468 print " xor cx,cx"
469 sub(/cmp /,"mov bx,")
470 sub(/i.*/,"i]")
471 print
472 $0=" cmp bh,2048/256"
473 }
474 if (/DGROUP:_buf2k\[bx\],0/) $0=" cmp word ptr [bx+" di "],cx"
475 sub(/,0/,",cx")
476 if (/\[.i\],cx/) isiso=14
477 else if (/mov/) next
478 }
479 if (/<< SECTORBITS/) isiso=9
480 if (isiso == 9) { # ISO9660.LST
481 if (/dx,/) next
482 sub(/mov ax,/,"les ax,d")
483 if (/^ call/) {
484 print " extrn N_LXLSH@ES:near"
485 sub(/N_LXLSH@/,"N_LXLSH@ES")
486 isiso=0
487 }
488 }
489 if (/filesize =/) isiso=8
490 if (isiso == 8) { # ISO9660.LST
491 if (/ax,/ || /cbw/) next
492 sub(/mov dx,/,"les dx,d")
493 sub(/\],ax/,"],es")
494 sub(/cx,/,"dx,")
495 if (/DGROUP:s@\+/) {
496 print
497 next
498 }
499 if (/i\+33]/) {
500 print " ifdef ROCKRIDGE"
501 print " ifdef BASIC_ISO9660"
502 print " add " di ",32"
503 print " mov ax,[" di "]"
504 print " else"
505 print " mov ax,[" di "+32]"
506 print " endif"
507 print " mov bl,ah"
508 print " mov bh,0"
509 print " else"
510 print " mov al,[" di "+33]"
511 print " cbw"
512 $0=" endif"
513 }
514 if (/sub/) {
515 print " ifdef ROCKRIDGE"
516 print " sub dx,bx"
517 print " else"
518 print
519 $0=" endif"
520 isiso=0
521 }
522 }
523 if (/entrysize =/) isiso=5
524 if (isiso == 5) { # ISO9660.LST
525 if (/ax,ax/) next
526 if (/word ptr \[.i\+3.\],ax/) next
527 sub(/ax/,"cx")
528 sub(/je/,"jcxz")
529 if (/jcxz/) {
530 hold=0
531 print s
532 print " stc"
533 print "returnCXZC:"
534 sub(/@1@1../,"returnC")
535 print
536 if (is386) $0=" mov dword ptr [" si "+6],eax"
537 else {
538 print " mov word ptr [" si "+8],dx"
539 $0=" mov word ptr [" si "+6],ax"
540 }
541 }
542 if (/return/) isiso=0
543 }
544 if (/do s\+\+; while/) isiso=3
545 if (isiso == 3) { # ISO9660.LST
546 if (/do \{/) print "while1:"
547 sub(/cmp byte ptr \[.i\]/,"sub al")
548 if (/inc /) { r=$2; print; next }
549 if (/al,0/) print " mov al,[" r "]"
550 if (/word ptr \[si\],-1/) $0=" not word ptr [si] ; zero'd in BSS"
551 sub(/al,32/,"ax,32")
552 if (/byte ptr \[si\+30\],al/) $0=" xchg ax,cx"
553 if (/al,byte ptr \[/) next
554 if (/byte ptr \[.*\],0/) next
555 if (/byte ptr \[si\+31\],al/) next
556 }
557 if (/ptr .isoreaddir/) {
558 print " ifdef ISOHOOK"
559 print " push cx"
560 print
561 print " pop cx"
562 print " else"
563 print
564 $0=" endif"
565 isiso=1
566 }
567 if (isiso == 1) { # ISO9660.LST
568 if (/xor/) {
569 $0=" xor cl,32"
570 isiso=18
571 }
572 if (/n = name;/) {
573 isiso=19
574 print " xchg dl,byte ptr [di] ; c"
575 }
576 sub(/jne/,"jnc")
577 if (/short @2@450/) $0=" jc returnC"
578 if (/je/) $0=" jc while1"
579 if (/short @2@562/) sub(/@2@562/,"jne_returnNotC")
580 if (/jmp/) $0=" jmp jne_returnNotC"
581 if (/ax,word ptr \[si\+4\]/) $0=" xchg ax,bx ; " $0
582 if (/\[di\],al/ || /al,byte ptr/) next
583 if (/@2@338/) next
584 if (/ax,-1/) next
585 if (/inc di/ || /@@0/) next
586 if (/@2@142$/) print " inc di"
587 }
588 if (/i\+34\]/) next
589 if (/di,offset DGROUP:_isostate/) {
590 sub(/mov/,";mov")
591 sub(/di,/,"si,")
592 swapsidi=1
593 }
594 if (/^ ret/) swapsidi=0
595 } # file == "iso9660.cpp"
596 if (wascall) {
597 if (rcall != "") {
598 if (/,ax$/) print " mov " rcall ",ax"
599 else print " xchg ax," rcall
600 wascall=0
601 }
602 else if (/^ mov .i,ax$/) {
603 split($2,y,",")
604 rcall=y[1]
605 next
606 }
607 else wascall=0
608 }
609 if (/^ call /) { wascall=1; rcall="" }
610 if (hold == 0) {
611 s=$0
612 if (/^ mov .[ix],bx$/ || /^ mov .[ix],.i$/) {
613 r=$2; kept=0
614 hold=1; split($2,regs,","); next
615 }
616 if (/^ inc e?.[ixhl]/ || /^ dec e?.[ixhl]/) {
617 hold=2; r=$2; next
618 }
619 if (/^ mov [abcds][ix],/ && ! /,.s/) {
620 hold=3; split($2,regs,","); next
621 }
622 if (/^ movzx eax,ax$/) { hold=4; next }
623 if (/^ cmp word ptr/ || /^ cmp [bcd]x,/) {
624 split($0,regs,",")
625 if (isnum(regs[2]) && regs[2] != 0 &&
626 (regs[2] % 256) == 0) {
627 hold=5; next
628 }
629 }
630 if (/^ mov ax,cs$/) { hold=6; kept=0; next }
631 if (/^ mov cl,4$/) { hold=7; next }
632 if (/^ cmp word ptr DGROUP:.*,0$/) {
633 hold=8; split($2,regs,","); next
634 }
635 if (/^ cbw/) { hold=11; kept=0; next }
636 if (/^ add [abcds][ix],2$/) {
637 split($2,regs,","); hold=12; next
638 }
639 if (/^ sub [abcds][ix],2$/) {
640 split($2,regs,","); hold=13; next
641 }
642 if (/^ push dx$/) {
643 hold=14; next;
644 }
645 }
646 else if (hold == 1) {
647 if (/^ ;/) { line[kept++]=$0; next }
648 hold=0; split($2,args,","); op=""
649 if ($1 == "add") op="+"
650 if ($1 == "sub") op="-"
651 if ($1 == "inc") { op="+"; args[2]="1"; }
652 if ($1 == "dec") { op="-"; args[2]="1"; }
653 if (op != "" && regs[1] == args[1]) {
654 if (isnum(args[2])) {
655 for (i = kept++; i > 0; i--) line[i] = line[i-1]
656 line[0] = "\tlea\t" regs[1] ",[" regs[2] op args[2] "]"
657 sub(/\+-/,"-",line[0])
658 hold=10; next
659 }
660 line[kept++]=$0
661 hold=1
662 next
663 }
664 if (/^ pop [ds]i/ && regs[2] ~ /^[ds]i$/) {
665 print " xchg " r
666 }
667 else print s
668 for (i = 0; i < kept; i++) print line[i]; kept=0
669 }
670 else if (hold == 2) {
671 split($0,args,",")
672 if (/^ mov / && r == args[2]) { print s; s=$0; next }
673 split($2,args,",")
674 hold=0; print s
675 if ($1 == "or" && r == args[1] && r == args[2]) next # don't clear C ...
676 }
677 else if (hold == 3) {
678 hold=0
679 if (/^ call / && regs[2] == "ax") s=" xchg ax," regs[1]
680 if (/^ add [abcds][ix],/) {
681 split($2,regs2,",")
682 if (regs[1] == regs2[1] && (regs2[2] == "offset" || isnum(regs2[2]))) {
683 t=$0; sub(/mov/,$1,s); sub(/add/,"mov",t)
684 print t; print s; next
685 }
686 }
687 print s
688 }
689 else if (hold == 4) {
690 hold=0
691 if (/^ push eax$/) {
692 print " push 0"; print " push ax"; next
693 } else { print s }
694 }
695 else if (hold == 5) {
696 hold=0
697 if ($1 == "jae" || $1 == "jb") {
698 sub(/word ptr/,"byte ptr",s); sub(/x,/,"h,",s) ||
699 sub(/\],/,"+1],",s) || sub(/,/,"+1,",s)
700 s = s "/256"
701 }
702 print s
703 }
704 else if (hold == 6) {
705 if (($1 == "and" || $1 == "add") && $2 ~ /^ax,/) {
706 line[kept++]=$0
707 next
708 }
709 p=$0
710 if (/^ movzx eax,ax$/) {
711 s=" mov eax,cs"; p=""
712 }
713 print s
714 for (i = 0; i < kept; i++) print line[i]; kept=0
715 if (p != "") print p
716 hold=0; next
717 }
718 else if (hold == 7) {
719 hold=0
720 if (/^ call near ptr N_LXURSH@$/) {
721 print " extrn N_LXURSH@4:near"
722 print " call near ptr N_LXURSH@4"
723 next
724 }
725 if (/^ call near ptr N_LXLSH@$/) {
726 print " extrn N_LXLSH@4:near"
727 print " call near ptr N_LXLSH@4"
728 next
729 }
730 print s
731 }
732 else if (hold == 8) {
733 if ($1 == "je" || $1 == "jne") { p=$0; hold=9; next }
734 hold=0
735 print s
736 }
737 else if (hold == 9) {
738 hold=0; split($2,args,",")
739 if (/^ mov ax,/ && args[2] == regs[1]) {
740 print; print " or ax,ax"; print p; next
741 }
742 print s; print p;
743 }
744 else if (hold == 10) {
745 split($2,args,","); op=""
746 if ($1 == "add") op="+"
747 if ($1 == "sub") op="-"
748 if ($1 == "inc") { op="+"; args[2]="1"; }
749 if ($1 == "dec") { op="-"; args[2]="1"; }
750 if (op != "" && isnum(args[2])) {
751 split(line[0],reg,",")
752 if (substr(reg[1],length(reg[1])-1,2) == args[1]) {
753 line[0] = substr(line[0],1,length(line[0])-1) op args[2] "]"
754 next
755 }
756 }
757 hold=0
758 if (/^ mov [sd]i,ax$/) {
759 split($2,args,",")
760 for (i = 0; i < kept; i++) {
761 sub(/ax/,args[1],line[i]); print line[i]
762 }
763 next
764 }
765 for (i = 0; i < kept; i++) print line[i]
766 }
767 else if (hold == 11) {
768 if (/^ inc ax$/ || /^ dec ax$/) {
769 line[kept++]=$0; next
770 }
771 split($2,args,",")
772 if (/^ mov cl,/) {
773 split($2,args,",")
774 if (args[2] >= 8) {
775 line[kept++]=$0; next
776 }
777 }
778 if (!/^ shl ax,/ || (args[2] != "cl" && args[2] < 8)) {
779 print " cbw "
780 }
781 for (i = 0; i < kept; i++) print line[i]
782 hold=kept=0
783 }
784 else if (hold == 12) {
785 hold=0
786 if ($1 != "adc" && $1 != "sbb" && ! /^ jn?[abc]/) {
787 print " inc " regs[1]
788 print " inc " regs[1]
789 }
790 else print " add " regs[1] ",2"
791 }
792 else if (hold == 13) {
793 hold=0
794 if ($1 != "adc" && $1 != "sbb" && ! /^ jn?[abc]/) {
795 print " dec " regs[1]
796 print " dec " regs[1]
797 }
798 else print " sub " regs[1] ",2"
799 }
800 else if (hold == 14) {
801 if (/^ push ax$/) { hold++; next; }
802 print " push dx";
803 hold=0;
804 }
805 else if (hold == 15) {
806 if (/^ pop eax$/) { hold++; next; }
807 print " push dx";
808 print " push ax";
809 hold=0;
810 }
811 else if (hold == 16) {
812 hold=0;
813 if (/^ shr eax,16$/) { print " xchg ax,dx"; next; }
814 print " push dx";
815 print " push ax";
816 print " pop eax";
817 }
818 else if (hold == 17) {
819 hold=0;
820 if (/^ cmp ax,-1$/) { print " inc ax"; next; }
821 }
822 if (/^ call near ptr @fileexist\$/ || # return boolean :
823 /^ call near ptr @isoreaddir\$/ || # 0=true, -1=false
824 /^ call near ptr @isoreset\$/ ||
825 /^ call near ptr @isoopen\$/ ||
826 /^ call near ptr @isoreadsector\$/ ||
827 /^ call near ptr @strhead\$/ ||
828 /^ call near ptr @strcmp\$/ ||
829 /^ call near ptr @argstr\$/ ||
830 /^ call near ptr @argnum\$/) { print; hold=17; next; }
831 s=$0
832 # These optimisation may break ZF or CF
833 if (/^ sub sp,2$/) { print " push ax"; next }
834 if (/^ sub sp,4$/) { print " push ax"; print " push ax"; next }
835 if (/^ add sp,4$/) { print " pop cx"; print " pop cx"; next }
836 if (/^ mov d*word ptr .*,0$/ || /^ mov dword ptr .*,large 0$/) {
837 sub(/mov/,"and",s); print s; next # slower
838 }
839 if (/^ mov d*word ptr .*,-1$/ || /^ mov dword ptr .*,large -1$/) {
840 sub(/mov/,"or",s); print s; next # slower
841 }
842 if (/^ or .*,0$/ || /^ and .*,-1$/) next
843 if (/^ or [abcd]x,/) {
844 split($2,args,",")
845 if (isnum(args[2]) && args[2] >= 0 && args[2] < 256) {
846 print " or " substr(args[1],1,1) "l," args[2]; next
847 }
848 }
849 if (/^ and [abcd]x,/) {
850 split($2,args,",")
851 if (isnum(args[2]) && args[2] >= -256 && args[2] < 0) {
852 print " and " substr(args[1],1,1) "l," args[2]; next
853 }
854 }
855 if (/^ or e[abcd]x,/) {
856 split($2,args,",")
857 if (args[2] == "large") { args[2] = $3 }
858 if (isnum(args[2]) && args[2] >= 0 && args[2] < 256) {
859 print " or " substr(args[1],2,1) "l," args[2]; next
860 }
861 }
862 if (/^ and e[abcd]x,/) {
863 split($2,args,",")
864 if (args[2] == "large") { args[2] = $3 }
865 if (isnum(args[2]) && args[2] >= -256 && args[2] < 0) {
866 print " and " substr(args[1],2,1) "l," args[2]; next
867 }
868 }
869 if (/^ or e[abcds][ix],/) {
870 split($2,args,",")
871 if (args[2] == "large") { args[2] = $3 }
872 if (isnum(args[2]) && args[2] >= 0 && args[2] < 65536) {
873 print " or " substr(args[1],2) "," args[2]; next
874 }
875 }
876 if (/^ and e[abcds][ix],/) {
877 split($2,args,",")
878 if (args[2] == "large") { args[2] = $3 }
879 if (isnum(args[2]) && args[2] >= -65536 && args[2] < 0) {
880 print " and " substr(args[1],2) "," args[2]; next
881 }
882 }
883 if (/^ add word ptr/ || /^ sub word ptr/ ||
884 /^ add [bcd]x,/ || /^ sub [bcd]x,/) {
885 split($0,args,",")
886 if (isnum(args[2]) && (args[2] % 256 == 0)) {
887 sub(/word ptr/,"byte ptr",s); sub(/x,/,"h,",s) ||
888 sub(/\],/,"+1],",s) || sub(/,/,"+1,",s)
889 print s "/256"; next
890 }
891 }
892 if (/^ add dword ptr/ || /^ sub dword ptr/) {
893 split($0,args,",")
894 if (args[2] == "large") { args[2] = $3 }
895 if (isnum(args[2])) {
896 if (args[2] % 16777216 == 0) {
897 sub(/dword/,"byte",s)
898 sub(/\],/,"+3],",s) || sub(/,/,"+3,",s)
899 print s "/16777216"; next
900 }
901 if (args[2] % 65536 == 0) {
902 sub(/dword/,"word",s)
903 sub(/\],/,"+2],",s) || sub(/,/,"+2,",s)
904 print s "/65536"; next
905 }
906 }
907 }
908 if (/^ mov e.x,/) {
909 split($2,args,",")
910 r=args[1]
911 if (args[2] == "large") { args[2] = $3 }
912 if (isnum(args[2]) && args[2] % 65536 == args[2]) {
913 if (args[2] % 256 == args[2] || args[2] % 256 == 0) {
914 print " xor " r "," r
915 if (args[2] == 0) next
916 x=" mov " substr(r,2,1)
917 if (args[2] % 256 == 0) {
918 print x "h," args[2] "/256"
919 }
920 else { print x "l," args[2] }
921 next
922 }
923 }
924 }
925 if (afterjmp) print ";" $0
926 else print
927 if (/^ jmp / || /boot_kernel\(\);/ ||
928 /^ call near ptr @die\$qpxzc/ ||
929 /^ call near ptr @exit\$qv/) afterjmp=1
930 }