Kevin O'Connor | 35f42dc | 2012-03-05 17:45:55 -0500 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | # Work around x86emu bugs by replacing problematic instructions. |
| 3 | # |
| 4 | # Copyright (C) 2012 Kevin O'Connor <kevin@koconnor.net> |
| 5 | # |
| 6 | # This file may be distributed under the terms of the GNU GPLv3 license. |
| 7 | |
| 8 | # The x86emu code widely used in Linux distributions when running Xorg |
| 9 | # in vesamode is known to have issues with "retl", "leavel", "entryl", |
| 10 | # and some variants of "calll". This code modifies those instructions |
| 11 | # (ret and leave) that are known to be generated by gcc to avoid |
| 12 | # triggering the x86emu bugs. |
| 13 | |
| 14 | # It is also known that the Windows vgabios emulator has issues with |
| 15 | # addressing negative offsets to the %esp register. That has been |
Kevin O'Connor | f9c3072 | 2012-12-07 12:23:27 -0500 | [diff] [blame] | 16 | # worked around by not using the gcc parameter "-fomit-frame-pointer" |
Kevin O'Connor | 35f42dc | 2012-03-05 17:45:55 -0500 | [diff] [blame] | 17 | # when compiling. |
| 18 | |
| 19 | import sys |
| 20 | |
| 21 | def main(): |
| 22 | infilename, outfilename = sys.argv[1:] |
| 23 | infile = open(infilename, 'rb') |
| 24 | out = [] |
| 25 | for line in infile: |
| 26 | sline = line.strip() |
| 27 | if sline == 'ret': |
| 28 | out.append('retw $2\n') |
| 29 | elif sline == 'leave': |
| 30 | out.append('movl %ebp, %esp ; popl %ebp\n') |
Kevin O'Connor | 9332f9b | 2013-11-30 12:52:44 -0500 | [diff] [blame] | 31 | elif sline.startswith('call'): |
| 32 | out.append('pushw %ax ; callw' + sline[4:] + '\n') |
Kevin O'Connor | 35f42dc | 2012-03-05 17:45:55 -0500 | [diff] [blame] | 33 | else: |
| 34 | out.append(line) |
| 35 | infile.close() |
| 36 | outfile = open(outfilename, 'wb') |
| 37 | outfile.write(''.join(out)) |
| 38 | outfile.close() |
| 39 | |
| 40 | if __name__ == '__main__': |
| 41 | main() |