Article View: comp.lang.pascal.borland
Article #286Patching the compiler
From: Robert AH Prins
Date: Tue, 08 Jun 1999 00:00
Date: Tue, 08 Jun 1999 00:00
683 lines
19281 bytes
19281 bytes
Hi all,
Apologies for this longish (aka downright bloody long) post... (an
UUencoded version of the text after this line would have been less than
half the length! Sorry, I don't have a website...)
As mentioned in earlier postings, I'm working on a disassembly of TP6'
TPC.EXE, and while doing so I have found that it is relatively easy to
modify BASM to add some useful new instructions. The original program
to do so was written in PL/I on the mainframe, but here is a translation
in our beloved Pascal dialect. As most of you are using BP 7, the
file "HASH.DAT" below is set up for BP 7.01 - see the requirements in
it.
NOTE: It was tested, although not exhaustedly, on TP6 and seems to be
working.
I do not have access to TP 6.01 or TP 7.00 SO DO NOT USE "HASH.DAT" TO
GENERATE NEW HASH TABLES FOR THEM, BUT
========================================================================
For users of the above, look at the EXE in something that allows you to
look at binaries in hex, and search for "DB" followed a bit further by
"DW", "DD", "LOCK". 37 bytes before "DB" you should see "1E 00", and
following those BP 7.01 shows "54 3E" and TP 6.00 "24 1E". These are
offsets in little-endian notation, their difference is 0x3E54 - 0x1E24 =
0x2034, which is exactly the difference between the entries for TP6 &
BP7 in the "HASH.DAT" below. So if your first two bytes after the "1E
00" would be "44 2E", you would quite likely have to use 0x13D0 +
(0x2E44 - 0x1E24) = 0x23F0 as the constant on the second line of
"HASH.DAT".
I tested the above on all 5 BP 7.01 compilers. The resulting "PATCH.DAT"
were byte-for-byte identical with the tables in these 5 executables. (Of
course I used the table below without the modifications, i.e. all "++"es
were changed back into "?+" and all "--"es into "?-"!)
========================================================================
Instructions:
1) cut the program and datafile from this posting
2) compile the program
3) run it
4) open a copy of BP.EXE in your favorite hex editor and replace
the 2706 bytes from offset 0x0FD6E with the 2706 from "PATCH.DAT"
5) enjoy...
NB:
- You know what you are doing, so the program doesn't contain any
error checking!!
- The version of "HASH.DAT" below will leave 28 bytes available in the
generated "PATCH.DAT" file, giving space for one or two of the "?+"
instructions. Adding any more will require the removal of some of the
"?-" instructions!
Needlessly to say, you've made a backup of your original files!
Have fun,
Robert
PS: Feel free to make this available on your website...
--- CUT --- CUT --- File: TPHASH.PAS --- CUT --- CUT ---
{-----------------------------------------------------------------------
(C) Copyright Robert AH Prins, 1999
This program may be used in any way you like as long as this copyright
message is not altered. If you make changes, I would appreciate a copy
of the changed source.
Legal stuff: If YOU screw up, it's YOUR problem!
TPHASH is program to generate alternative instruction set hash-tables
for the built-in assembler in the TP V6.00 & BP V7.01 compilers,
allowing the direct use of some 386+ instructions.
-----------------------------------------------------------------------}
program tphash;
type
wp = ^word;
hashptr = ^hash_list;
hash_list =
record
hash_nxt : hashptr;
hash_hash: byte;
hash_rec : string[255];
end;
hash_rec =
record
hash_addr: hashptr;
hash_hash: integer;
hash_size: integer;
hash_bits: array [0..55] of byte;
end;
const
hash_ptr: hashptr = nil;
hash_top: hashptr = nil;
hash_end: hashptr = nil;
var
hashin: text;
optab : file;
inrec : string[255];
_,
__,
_a,
_h,
_i,
_l,
_p,
_pl,
_r,
h,
i,
j,
org,
p,
size: integer;
c,
pl: char;
hash_tab : array [1..512] of hash_rec;
hash_word: array [1..1353] of word;
hash_byte: array [1..2706] of byte absolute hash_word;
{*
* This procedure converts a character string to its binary equivalent
* NB: I could have used VAL...
*}
function c2x(c: string): longint;
var r: longint;
var i: longint;
begin
r:= 0;
for i:= 1 to length(c) do
begin
r:= r shl 4;
case c[i] of
'0': r:= r;
'1': r:= r + 1;
'2': r:= r + 2;
'3': r:= r + 3;
'4': r:= r + 4;
'5': r:= r + 5;
'6': r:= r + 6;
'7': r:= r + 7;
'8': r:= r + 8;
'9': r:= r + 9;
'A': r:= r + 10;
'B': r:= r + 11;
'C': r:= r + 12;
'D': r:= r + 13;
'E': r:= r + 14;
'F': r:= r + 15;
end;
end;
c2x:= r;
end; {c2x}
procedure update_list_pointers; assembler;
asm
mov dx, di
db $66; mov ax, [di + 4]
db $66; or ax, ax
db $66; mov ax, [di]
jnz @1
db $66; mov [di + 4], ax
jmp @2
@1:
les di, [di + 8]
db $66; mov es:[di], ax
@2:
mov di, dx
db $66; mov [di + 8], ax
ret
nop
end; {update_list_pointers}
function ptr_2_long(p: pointer): longint; assembler;
asm
mov ax, word ptr p
mov dx, word ptr p + 2
mov bx, dx
shr dx, 12
shl bx, 4
add ax, bx
adc dx, 0
and dx, 0fh
end; {ptr_2_long}
function long_2_ptr(l: longint): pointer; assembler;
asm
mov ax, word ptr l
mov dx, word ptr l + 2
shl dx, 12
mov bx, ax
shr bx, 4
add dx, bx
and ax, 0fh
end; {long_2_ptr}
procedure use_it;
begin
inc(_r);
new(hash_ptr);
asm
mov di, offset hash_ptr
call update_list_pointers
end;
fillchar(hash_ptr^, sizeof(hash_list), 0);
hash_ptr^.hash_rec:= inrec;
end; {use_it}
begin
_r := 0;
size:= 0;
fillchar(hash_tab, sizeof(hash_tab), 0);
assign(hashin, 'HASH.DAT');
reset (hashin);
readln(hashin, inrec);
org:= c2x(copy(inrec, 3, 4));
readln(hashin, inrec);
_a:= c2x(copy(inrec, 3, 4));
_h:= _a + 2;
repeat
readln(hashin, inrec);
if (inrec[1] = '{') then
begin;
end
else
if ((inrec[1] = ' ') and (inrec[2] = ' ')) or
((inrec[1] = '+') and (inrec[2] = '+')) then
begin
use_it;
end
else
if (inrec[1] = '-') and (inrec[2] = '-') then
begin;
writeln('Omitting ',
copy(inrec, 5, 7),
' instruction from compiler patch file');
end
else
if (inrec[1] = '?') and (inrec[2] = '-') then
begin;
use_it;
writeln('Including potential candidate for removal ',
copy(inrec, 5, 7));
end
else
if (inrec[1] = '?') and (inrec[2] = '+') then
begin;
writeln('Skipping potential candidate for inclusion ',
copy(inrec, 5, 7));
end;
fillchar(inrec, sizeof(inrec), ' ');
until eof(hashin);
close(hashin);
_i:= 0;
hash_ptr:= hash_top;
while hash_ptr <> nil do
begin
inc(_i);
hash_tab[_i].hash_addr:= hash_ptr;
inrec := hash_ptr^.hash_rec;
pl:= inrec[3];
val(pl, _pl, _);
hash_tab[_i].hash_bits[3]:= _pl;
hash_tab[_i].hash_size := _pl + 3;
_p:= 4;
_ := 0;
_l:= 5;
repeat
c := inrec[_l];
hash_tab[_i].hash_bits[_p]:= byte(c);
inc(_p);
__:= byte(c);
_ := (_ + __ - 1) mod 256;
inc(_l);
until _l = (5 + _pl);
_ := (_ * 2) mod 256;
_ := _ and _a;
hash_tab[_i].hash_bits[0]:= _;
hash_tab[_i].hash_hash := _;
_l:= 13;
repeat
i := c2x(copy(inrec, _l, 2));
hash_tab[_i].hash_bits[_p]:= i;
inc(hash_tab[_i].hash_size);
inc(_p);
inc(_l, 3);
until _l > length(inrec);
inc(size, hash_tab[_i].hash_size);
hash_ptr:= hash_ptr^.hash_nxt;
end;
if size > 2706 then
begin
writeln('Hash table exceeds maximum allowable size of 2706
bytes');
writeln;
writeln('Remove some templates from the source file and rerun');
halt(12);
end;
fillchar(hash_word, sizeof(hash_word), 0);
hash_word[1]:= _a;
_p:= 2 + _h + 1;
for i:= 1 to _r do
begin
hash_tab[i].hash_addr:= ptr(seg(hash_word),
ofs(hash_word) + _p - 1);
for j:= 1 to hash_tab[i].hash_size do
begin
hash_byte[_p]:= hash_tab[i].hash_bits[j];
inc(_p);
end;
end;
hash_ptr:= long_2_ptr(ptr_2_long(@hash_word) - org);
for i:= 1 to _r do
begin
p:= hash_tab[i].hash_hash div 2 + 1;
h:= ptr_2_long(hash_tab[i].hash_addr) - ptr_2_long(hash_ptr);
if hash_word[p + 1] <> 0 then
wp(hash_tab[i].hash_addr)^:= hash_word[succ(p)];
hash_word[succ(p)]:= h;
end;
assign(optab, 'PATCH.DAT');
rewrite(optab, 1);
blockwrite(optab, hash_byte, sizeof(hash_byte));
close(optab);
end. {tphash}
--- CUT --- CUT --- File: HASH.DAT --- CUT --- CUT ---
4F6E <-+
001E | <- Can be changed if you know what you're doing...
{ 13D0 --+ TPC.EXE, 23-10-90, 6:00:00, 69214, insert @ 0x0ECB0
{ | Old bytes @ 0x0ECB0: 1E 00 24 1E AB 1B 3F 1E
{ |
{ 13C2 --+ TPCX.EXE, 23-10-90, 7:00:00, 216119, insert @ 0x2A539
{ | Old bytes @ 0x2A539: 1E 00 16 1E 9D 1B 31 1E
{ |
{ 13C2 --+ TURBO.EXE, 23-10-90, 6:00:00, 325397, insert @ 0x034031
{ | Old bytes @ 0x34031: 1E 00 16 1E 9D 1B 31 1E
{ |
{ |
{ 3404 --+ BPC.EXE, 09-03-93, 7:01:00, 125002, insert @ 0x11804
{ | Old bytes @ 0x11804: 1E 00 58 3E DF 3B 73 3E
{ |
{ 4F6E --+ BP.EXE, 09-03-93, 7:01:00, 499217, insert @ 0x0FD6E
{ | Old bytes @ 0x0FD6E: 1E 00 C2 59 49 57 DD 59
{ |
{ 13E2 --+ BPW.EXE, 09-03-93, 7:01:00, 518672, insert @ 0x403E2
{ | Old bytes @ 0x403E2: 1E 00 36 1E BD 1B 51 1E
{ |
{ 13E2 --+ TURBO.EXE, 09-03-93, 7:01:00, 403839, insert @ 0x4C876
{ | Old bytes @ 0x4C876: 1E 00 36 1E BD 1B 51 1E
{ |
{ 13E8 --+ TPC.EXE, 09-03-93, 7:01:00, 75432, insert @ 0x0DF58
{ Old bytes @ 0x0DF58: 1E 00 3C 1E C3 1B 57 1E
{
{ Pos 1..2: ' ': include in hash table
{ '++': newly added instruction
{ '--': deleted instruction (obsolete/duplicate)
{ '?-': included but might be deleted, is synonym
{ '?+': not included, might be useful
{ '{ ': comment, will be ignored
{
{ This file adds the following instructions:
{
{ - SEGFS : segment overrides
{ - SEGGS : segment overrides
{ - CDQ : sign-extend EAX into EDX:EAX
{ - CWDE : sign-extend AX into EAX
{ - MOVSD : move dword
{ - STOSD : store dword
{ - RDTSC : read timestamp counter
{
{ This file removes the following instructions:
{
{ - ENTER : set up stack-frame (slow on Pentium+)
{ - LEAVE : discard stack-frame (slow on Pentium+)
{ - SAL : synonym of SHL
{ - FNOP : use NOP if you need it
{ - FSETPM : obsolete on 386+
{ - F(N)DISI: 8087 only, obsolete
{ - F(N)ENI : 8087 only, obsolete
{
{ This file corrects the following instruction:
{
{ - FLDLN2 : this is a valid 8087 instruction (error on TP6)
{
2 DB EA 01
2 DW EA 02
2 DD EA 04
4 LOCK AE 00 F0
3 REP AE 00 F3
4 REPE AE 00 F3
4 REPZ AE 00 F3
5 REPNE AE 00 F2
5 REPNZ AE 00 F2
5 SEGES AE 00 26
5 SEGCS AE 00 2E
5 SEGSS AE 00 36
5 SEGDS AE 00 3E
++5 SEGFS AE 04 64
++5 SEGGS AE 04 65
3 ADC 98 80 14 C2 80 10 48 90 80
3 ADD 98 80 04 C2 80 00 48 80 80
3 AND 98 80 24 C2 80 20 4A A0 80
3 AAA 00 00 37
3 AAS 00 00 3F
3 AAD 80 01 D5 0A 04 40 D5
3 AAM 80 01 D4 0A 04 40 D4
5 BOUND 4E 84 62
4 CALL A4 40 E8 9E 40 9A 9C 50 FF 20 58 FF
3 CMP 98 80 3C C2 80 38 48 B8 80
3 CBW 00 00 98
3 CWD 00 00 99
++3 CDQ 00 05 66 99
++4 CWDE 00 05 66 98
3 CLC 00 00 F8
3 CLD 00 00 FC
3 CLI 00 00 FA
3 CMC 00 00 F5
5 CMPSB 00 00 A6
5 CMPSW 00 00 A7
?+5 CMPSD 00 05 66 A7
3 DAA 00 00 27
3 DAS 00 00 2F
3 DEC B4 40 48 4C 48 FE
3 DIV 4C 70 F6
--5 ENTER 16 84 C8
3 HLT 00 00 F4
4 IDIV 4C 78 F6
4 IMUL CC 68 F6 3C C4 69
2 IN 8C 80 EC 0E 80 E4
3 INC B4 40 40 4C 40 FE
4 INSB 00 04 6C
4 INSW 00 04 6D
3 INT 14 40 CC
4 INTO 00 00 CE
4 IRET 00 00 CF
3 JMP A2 40 EB A4 40 E9 9E 40 EA 9C 60 FF 20 68 FF
2 JO 22 40 70
3 JNO 22 40 71
2 JC 22 40 72
2 JB 22 40 72
?-4 JNAE 22 40 72
3 JNC 22 40 73
3 JAE 22 40 73
?-3 JNB 22 40 73
2 JE 22 40 74
2 JZ 22 40 74
3 JNE 22 40 75
3 JNZ 22 40 75
3 JBE 22 40 76
?-3 JNA 22 40 76
2 JA 22 40 77
?-4 JNBE 22 40 77
2 JS 22 40 78
3 JNS 22 40 79
?-2 JP 22 40 7A
3 JPE 22 40 7A
?-3 JNP 22 40 7B
3 JPO 22 40 7B
2 JL 22 40 7C
?-4 JNGE 22 40 7C
3 JGE 22 40 7D
?-3 JNL 22 40 7D
3 JLE 22 40 7E
?-3 JNG 22 40 7E
2 JG 22 40 7F
?-4 JNLE 22 40 7F
4 JCXZ 22 40 E3
4 LAHF 00 00 9F
3 LDS 4E 80 C5
3 LEA 06 80 8D
--5 LEAVE 00 04 C9
3 LES 4E 80 C4
5 LODSB 00 00 AC
5 LODSW 00 00 AD
?+5 LODSD 00 05 66 AD
4 LOOP 22 40 E2
5 LOOPE 22 40 E1
?-5 LOOPZ 22 40 E1
6 LOOPNE 22 40 E0
?-6 LOOPNZ 22 40 E0
3 MOV A8 80 A0 A6 80 A2 9A 80 B0 CA 80 C6 C2 80 88 C0 80 8C 3E 80
8E
5 MOVSB 00 00 A4
5 MOVSW 00 00 A5
++5 MOVSD 00 05 66 A5
3 MUL 4C 60 F6
3 NEG 4C 58 F6
3 NOP 00 00 90
3 NOT 4C 50 F6
2 OR 98 80 0C C2 80 08 4A 88 80
3 OUT 88 80 EE 0A 80 E6
5 OUTSB 00 04 6E
5 OUTSW 00 04 6F
3 POP B4 40 58 B2 40 07 46 40 8F
4 POPA 00 04 61
?+5 POPAD 00 05 66 61
4 POPF 00 00 9D
4 PUSH B4 40 50 B0 40 06 C6 70 FF 84 44 6A 02 44 68
5 PUSHA 00 04 60
?+6 PUSHAD 00 05 66 60
5 PUSHF 00 00 9C
3 RET AA 00 C3 2A 40 C2
4 RETN 80 00 C3 2C 40 C2
4 RETF 80 00 CB 2C 40 CA
3 SUB 98 80 2C C2 80 28 48 A8 80
3 SBB 98 80 1C C2 80 18 48 98 80
3 RCL 50 90 D0
3 RCR 50 98 D0
3 ROL 50 80 D0
3 ROR 50 88 D0
--3 SAL 50 A0 D0
3 SHL 50 A0 D0
3 SAR 50 B8 D0
3 SHR 50 A8 D0
4 SAHF 00 00 9E
5 SCASB 00 00 AE
5 SCASW 00 00 AF
?+5 SCASD 00 05 66 AF
3 STC 00 00 F9
3 STD 00 00 FD
3 STI 00 00 FB
5 STOSB 00 00 AA
5 STOSW 00 00 AB
++5 STOSD 00 05 66 AB
4 TEST 98 80 A8 CA 80 F6 44 80 84
4 WAIT 00 00 9B
4 XCHG 90 80 90 92 80 90 44 80 86
4 XLAT 00 00 D7
3 XOR 98 80 34 C2 80 30 4A B0 80
4 ARPL 3A 84 63
3 LAR 38 85 0F 02
4 CLTS 00 05 0F 06
4 LGDT 36 55 0F 01
4 SGDT 36 45 0F 01
4 LIDT 36 5D 0F 01
4 SIDT 36 4D 0F 01
4 LLDT 46 55 0F 00
4 SLDT 46 45 0F 00
4 LMSW 46 75 0F 01
4 SMSW 46 65 0F 01
3 LSL 38 85 0F 03
3 LTR 46 5D 0F 00
3 STR 46 4D 0F 00
4 VERR 46 65 0F 00
4 VERW 46 6D 0F 00
?+5 WRMSR 00 05 0F 30
++5 RDTSC 00 05 0F 31
?+5 RDMSR 00 05 0F 32
?+5 RDPMC 00 05 0F 33
3 FLD D2 01 D9 C1 D6 41 D9 C0 DC 40 D9 5E 68 DB
4 FILD E2 40 DB 64 68 DF
3 FST D2 01 DD D1 D6 41 DD D0 5C 50 D9
4 FSTP D2 01 DD D9 D6 41 DD D8 DC 58 D9 5E 78 DB
4 FIST 62 50 DB
5 FISTP E2 58 DB 64 78 DF
4 FADD D2 01 DE C1 DA 81 D8 C0 D8 81 DC C0 5C 40 D8
5 FADDP D2 01 DE C1 58 81 DE C0
5 FIADD 62 40 DA
4 FSUB D2 01 DE E9 DA 81 D8 E0 D8 81 DC E8 5C 60 D8
5 FSUBP D2 01 DE E9 58 81 DE E8
5 FSUBR D2 01 DE E1 DA 81 D8 E8 D8 81 DC E0 5C 68 D8
6 FSUBRP D2 01 DE E1 58 81 DE E0
5 FISUB 62 60 DA
6 FISUBR 62 68 DA
4 FMUL D2 01 DE C9 DA 81 D8 C8 D8 81 DC C8 5C 48 D8
5 FMULP D2 01 DE C9 58 81 DE C8
5 FIMUL 62 48 DA
4 FDIV D2 01 DE F9 DA 81 D8 F0 D8 81 DC F8 5C 70 D8
5 FDIVP D2 01 DE F9 58 81 DE F8
5 FDIVR D2 01 DE F1 DA 81 D8 F8 D8 81 DC F0 5C 78 D8
6 FDIVRP D2 01 DE F1 58 81 DE F0
5 FIDIV 62 70 DA
6 FIDIVR 62 78 DA
4 FCOM D2 01 D8 D1 D6 41 D8 D0 5C 50 D8
5 FCOMP D2 01 D8 D9 D6 41 D8 D8 5C 58 D8
6 FCOMPP 52 01 DE D9
5 FICOM 62 50 DA
6 FICOMP 62 58 DA
5 F2XM1 52 01 D9 F0
4 FABS 52 01 D9 E1
4 FBLD 5E 60 DF
5 FBSTP 5E 70 DF
4 FCHS 52 01 D9 E0
7 FDECSTP 52 01 D9 F6
5 FFREE 56 41 DD C0
7 FINCSTP 52 01 D9 F7
4 FLD1 52 01 D9 E8
5 FLDCW 60 68 D9
6 FLDENV 66 60 D9
6 FLDL2E 52 01 D9 EA
6 FLDL2T 52 01 D9 E9
6 FLDLG2 52 01 D9 EC
6 FLDLN2 52 01 D9 ED
5 FLDPI 52 01 D9 EB
4 FLDZ 52 01 D9 EE
--4 FNOP 52 01 D9 D0
6 FPATAN 52 01 D9 F3
5 FPREM 52 01 D9 F8
5 FPTAN 52 01 D9 F2
7 FRNDINT 52 01 D9 FC
6 FRSTOR 68 60 DD
6 FSCALE 52 01 D9 FD
--6 FSETPM 52 05 DB E4
5 FSQRT 52 01 D9 FA
4 FTST 52 01 D9 E4
5 FWAIT 52 00 9B
4 FXAM 52 01 D9 E5
4 FXCH D2 01 D9 C9 56 41 D9 C8
7 FXTRACT 52 01 D9 F4
5 FYL2X 52 01 D9 F1
7 FYL2XP1 52 01 D9 F9
5 FCLEX 52 02 01 DB E2
6 FNCLEX 52 02 00 DB E2
--5 FDISI 52 02 01 DB E1
--6 FNDISI 52 02 00 DB E1
--4 FENI 52 02 01 DB E0
--5 FNENI 52 02 00 DB E0
5 FINIT 52 02 01 DB E3
6 FNINIT 52 02 00 DB E3
5 FSAVE 68 71 01 DD
6 FNSAVE 68 71 00 DD
5 FSTCW 60 79 01 D9
6 FNSTCW 60 79 00 D9
6 FSTENV 66 71 01 D9
7 FNSTENV 66 71 00 D9
5 FSTSW E0 79 01 DD 54 46 01 DF E0
6 FNSTSW E0 79 00 DD 54 46 00 DF E0
--- CUT --- CUT ---
Robert
--
Robert AH Prins
prinsra@williscorroon.com
PS: I am pretty convinced that a small TSR would allow the use of most,
if not all, non-SIB instructions, including MMX/SSE.
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
Technical Details
Message-ID:
<7jjjag$qod$1@nnrp1.deja.com>Path:
arc1-ca.pugleaf.net!unknown!not-for-mailShow Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 108ebd,86137679503eab26,start X-Google-Attributes: gid108ebd,public X-Google-Thread: 111659,86137679503eab26,start X-Google-Attributes: gid111659,public From: Robert AH Prins <prinsra@williscorroon.com> Subject: Patching the compiler Date: 1999/06/08 Message-ID: <7jjjag$qod$1@nnrp1.deja.com> X-Deja-AN: 487121377 X-Http-Proxy: 1.0 x39.deja.com:80 (Squid/1.1.22) for client 193.130.234.1 Organization: Deja.com - Share what you know. Learn what you don't. X-Article-Creation-Date: Tue Jun 08 17:19:26 1999 GMT Newsgroups: comp.lang.pascal.borland,borland.public.turbopascal X-Http-User-Agent: Mozilla/4.05 [en] (WinNT; I)