========================================================================================== RDP.ERR ========================================================================================== %NONAME-F-NOMSG, Message number 00000004 %TRACE-F-TRACEBACK, symbolic stack dump follows module name routine name line rel PC abs PC 00088808 00088808 00088956 00088956 TMNEXE _RTV_SCODE 00000419 00023F9B TMNACT _RTV_SCODE 000001F7 000251A3 TMNQUE _RTV_SCODE 000001B0 00024443 TMNAIN _RTV_SCODE 000000A8 00023382 RRJOB _RTV_SCODE 00000022 0001F917 00088693 00088693 TRUTSECT TRUTSECT 000002A6 00002A8E ========================================================================================== RDP.OUT ========================================================================================== Exception PC = 8A15 RDP RTL/2 ERROR 4 (ARRAY BOUND CHECK VIOLATION) ========================================================================================== Analysis ========================================================================================== (a) Exception PC inside module TRMTMA TRMTMA SDM-230106-V211 1596 [TRIMMEL.REL.SDM2301]TRMLIB.OLB;3 28-JUN-2004 11:22 VAX MACRO V5.4-3 TRMTMA 00000A94 00000A9C 00000009 ( 9.) LONG 2 TRMTMA 0000870B 00008D32 00000628 ( 1576.) BYTE 0 TRMTMA 00030ED6 00030EE0 0000000B ( 11.) BYTE 0 (b) Relative PC inside TRMTMA 0x0000030A (=0x00008A15-0x0000870B) (c) Macro listing shows that "INDEX R3,#^X1,R1,#^X1,#^X0,R3" triggered the fault 50 02 A6 D0 02FA 833 MOVL ^X2(R6),R0 ; 1405 51 18AA C0 32 02FE 834 CVTWL ^X18AA(R0),R1 53 00 01 51 01 53 0A 0303 835 INDEX R3,#^X1,R1,#^X1,#^X0,R3 51 00000006'GF D0 030A 836 MOVL G^B126TMA+^X6,R1 56 68 A1 32 0311 837 CVTWL ^X68(R1),R6 0000006A 8F 56 01 53 0A 0315 838 INDEX R3,#^X1,R6,#^X6A,#^X0,R5 <---- here we are 55 00 031E 55 6145 9E 0320 839 MOVAB (R1)[R5],R5 56 01 32 0324 840 CVTWL #^X1,R6 57 20 A5 32 0327 841 CVTWL ^X20(R5),R7 (d) RTL listing near line 1405 shows % Store Runway Data % %V210% BTDGM.RWY1(I) := BTMAIDX(I).RWY(1); %V210% BTDGM.RWY2(I) := BTMAIDX(I).RWY(2); %V210% BTDGM.RWY3(I) := BTMAIDX(I).RWY(3); %V210% BTDGM.RWY4(I) := BTMAIDX(I).RWY(4); %V210% (e) runtime TRACE output shows <230106/007> <11:34:25.23> STORE RWY DATA FOR INDEX INTEGER I = ^X0006 OCT 000006 6 INTEGER LENGTH(BTMAIDX) = ^X0006 OCT 000006 6 INTEGER LENGTH(BTDGM.RWY1) = ^XFFFF OCT 177777 -1 INTEGER LENGTH(BTDGM.RWY2) = ^X0006 OCT 000006 6 INTEGER LENGTH(BTDGM.RWY3) = ^X0006 OCT 000006 6 INTEGER LENGTH(BTDGM.RWY4) = ^X0006 OCT 000006 6 ========================================================================================== Conclusion ========================================================================================== LENGTH(BTDGM.RWY1) becomes -1, so the length word of the array BTDGM.RW1 has been overwritten by some instruction performed earlier. ========================================================================================== Findings ========================================================================================== (a) the memory layout of BTDGM is - roughly - as follows: 000B 387 ; Mode MRECTDGM 000B 388 ; 000B 389 ; 0 ERRORFLG 000B 390 ; 2 ERRORRPT 000B 391 ; 4 CONSTAT 000B 392 ; 6 PPF 000B 393 ; 8 SERVICE ............. -- 16bit length word 000B 445 ; 1887 ATIS / 000B 446 ; 188E CONVALT v 000B 447 ; 189C QNHDH [6] [0006][0000][0000][0000][0000][0000][0000] 000B 448 ; 18AB RWY1 [6] [0006][0000][0000][0000][0000][0000][0000] 000B 449 ; 18B3 RWY2 [6] .... 000B 450 ; 18BB RWY3 [6] 000B 451 ; 18C3 RWY4 [6] 000B 452 ; 18CA IQNHNEW 000B 453 ; 18CC IQNHOLD 000B 454 ; 18CF QNH NOTE: Arrays in RTL have a length WORD as a counter for the max. index allowed. This counter is checked against the INDEX instruction to avoid buffer overflows. The interesting variable is QNHDH, an array of 6 WORDs, located right before the RWY1 array, which has been corrupted. QNHDH is beeing initialised with a statement containing an integer division ( ':/' on RTL): BTDGM.QNHDH(I):=BTMAIDX(I).HTERR:/100; Once 'I' - the index - becomes 6, the following behavior has been identified: BEFORE this instruction, the length word for RWY1 contains 0x0006, which is expected. AFTER this instruction, the length word for RWY1 contains 0xFFFF, which is NOT expected. It can clearly be shown that the division performed for the last index (6) destroys the contents of the following memory location. In this case it is the length word for the array RWY1. (b) DIVW3 seems to behave oddly: The RTL compiler produced this MACRO/11 instruction for the division: "DIVW3 #^X64,^X12(R8),^X189C(R0)[R3]" ^X189C is the offset of the destination (QNHDH) R3 holds the index (in our case 6) R0 hold the base address of the destination ^X12 is the offset of the source R8 holds the base adddress of the source #^X64 is the short literal (100) for the division This instruction stores a LONG to the destination ^X189C(R0)[R3] !!! (c) If we change the program slightly by introducing a temporary variabe T T := BTMAIDX(I).HTERR:/100; BTDGM.QNHDH(I) := T; we get the following MACRO/11 instruction, which behaves as expected. "DIVW3 #^X64,^X12(R8),^X3(R7)" **** something's wrong with DIVW3 instruction emulation ****