Individual Entry

MOVPSL — I've a feeling we're not in Kansas anymore!

Having just completed the latest round of new features for the TMESIS DCL Debugger, it was time to build and test the code on all three OpenVMS Architectures — VAX, Alpha and Itanium. The development of the project had been seeded on the Alpha; thus, that's where it has remained to this day. When a new feature or bug fix has been vetted on the Alpha, the code is then built and checked on OpenVMS VAX and OpenVMS Itanium. Everything newly added was working fine on all three platforms, so it was time to run through some of the regression tests. What this uncovered surprized me. The EDIT functions, which had nothing to do with the newly added functionality, were failing on the Itanium. Never underestimate the need to perform regression testing!

It was time to have a look-see into what was causing the TMESIS DCL Debugger to process stack dump when any of its EDIT functions were invoked. The TMESIS DCL Debugger uses the OpenVMS callable editors to create and edit its MACROS, as well as to edit the procedure that is being debugged. To allow the user a selectable preference for the OpenVMS editor of his or her choice, the editor is dynamically activated using LIB$FIND_IMAGE_SYMBOL. This was working and working without issue prior to the newly added functionality. Perhaps, there was an edit where I accidentally trampled on one of the routines. However, since the editor is invoked dynamically in three separate routines, I thought this to be a specious conclusion. Differencing the current edit with a prior generation proved that this was not the case. All the code check out the same and all in tact.

What could be causing these, formerly functioning, features to suddenly cause a process stack dump? I reviewed the values in the process stack dump. The TMESIS DCL Debugger was crashing with an ACCVIO (ACCess VIOlation) and its PC (Program Counter) was in the code. I pulled up the latest build .MAP and .LISting files to resolve the PC address. The PC lead me to the entry of an SSI (System Service Intercept) trap routine in my code. One of the routines I'd newly created in the course of adding the new functionality. I scratched my head for a moment while puzzlingly reviewing the routine.

The obvious course of thought was to comment out the code where the SSI$DECLARE_INTERCEPT installed this trap routine. I built and installed the code and, sure as eggs is eggs, the edit functions worked flawlessly. Now, the question was, what is causing this to invoke the process stack dump when the editor is invoked?

The trap was relatively simple. It determined the current mode and, if not USER mode, it would return. If is was USER mode, it rewrote an argument in the argument list for a particular system service. This particular system service wouldn't, couldn't, shouldn't be called in the course of editing a file but I decided to elide the code in the trap just to be sure. I built, installed and tested the code with this trap elided. Again, however, calling up one of the editing functions caused a process stack dump.

I studied this most recent process stack dump carefully. I noticed a system space address in the R16 register. In system service dispatching on Integrity, R16 holds the FD (Function Descriptor) of the system service to be handled by the change mode dispatcher. I pondered as to what service this could be and, perhaps, knowning which service might shed some light on why the code is crashing. I called up the system analyzer (SDA) and had a look-see.

Its address turned out to be for the SWIS (SoftWare Interrupt Services) routine SYS$PAL_RD_PS. But why? I didn't invoke this routine, nor did I use the Macro built-in EVAX_RD_PD. The only thing in my trap routine was a MOVPSL — a VAX instruction primitive. However, this being compiled Macro on Itanium, I had a look at the Itanium machine code in the .LISting. There is was! The Macro compiler on Itanium invokes SYS$PAL_RD_PS to provide the MOVPSL functionality. But why should a MOVPSL cause an access violation? It was time to investigate this phenomenon further.

The first ting I did was to create a small program pared down to the basic functions involved based upon what was in the TMESIS DCL Debugger — callable edit and a system servcie interrupt routine. The code follows. If you are unfamiliar with SSI (System Service Interrupts), I suggest tht you read up on them by following this link:

http://h71000.www7.hp.com/openvms/journal/v8/ssi.pdf.


.LIBRARY "SYS$LIBRARY:LIB.MLB"
$SSIDEF ; System Service Intercept DEFinitions

.PSECT DATA,WRT,NOEXE,5
SSI.BLOCK: .LONG 0[SSI$S_SSI_BLOCK/4]

EDTSHR: .ASCID "EDTSHR"
.ALIGN QUAD
EDT$EDIT: .ASCID "EDT$EDIT"
.ALIGN QUAD
EDT$M_NOJOURNAL:.ASCID "EDT$M_NOJOURNAL"
.ALIGN QUAD
FILENAME: .ASCID "TEST.TXT"

.PSECT CODE,NOWRT,EXE,5
.ENTRY GO,0

CLRL -(SP) ; stack for EDT$M_NOJOURNAL value
PUSHAL (SP)
PUSHAL EDT$M_NOJOURNAL
PUSHAL EDTSHR
CALLS #3,G^LIB$FIND_IMAGE_SYMBOL

CLRL -(SP) ; stack for EDT$EDIT entry address
PUSHAL (SP)
PUSHAL EDT$EDIT
PUSHAL EDTSHR
CALLS #3,G^LIB$FIND_IMAGE_SYMBOL

MOVAL SSI.BLOCK,R0
MOVL #SSI$C_VERSION_QUAD_LIST,SSI$L_VERSION(R0)
MOVAL SSI.PRE_TRAP,SSI$PS_PRE_ROUTINE(R0)
$SSI_DECLARE_INTERCEPT_S ssi_block_ptr = SSI.BLOCK

MOVL (SP)+,R0 ; EDT$EDIT entry address => R0

PUSHAL (SP) ; EDT$M_NOJOURNAL by reference
PUSHL #0
PUSHL #0
PUSHL #0
PUSHAL FILENAME
CALLS #5,(R0)

RET

;;;PUKE_MOVPSL = 1

$OFFDEF SS_TRAP,<-
ARG_PTR,- ; service argument list pointer (quad)
SSV_SYS,- ; service PD/FD (system address space)
SSV_PRC,- ; service PD/FD (process address space)
RET_ADR,- ; return address into SSI trap service
SSI_PTR,- ; address of the original SSI structure
>

.ENTRY SSI.PRE_TRAP,0

.IIF DF,PUKE_MOVPSL, MOVPSL R0 ; will barf

MOVL #1,R0
RET

.END GO

The above code, compiled as-is and linked, will successfully invoke the EDT editor to edit the file TEST.TXT. Remove the comments from the line:
;;;PUKE_MOVPSL = 1
... and compile and link it and the program will process stack dump when it is executed.

So, what's happening here to cause this? The symbol SYS$PAL_RD_PS is, as are all of the system services, define in the image SYS$PUBLIC_VECTORS.EXE. If you've read the article, referenced above, about SSI, you will know that the SSI defines its own vectors to supplant those in SYS$PUBLIC_VECTORS.EXE. Because SYS$PAL_RD_PS is one of those vectors, it too is subject to SSI. So, what is happening is that the MOVPSL in the SSI trap routine is being recursively intercepted! Eventually, the trap routine can not be invoked and there's an access violation.

By now you're probably thinking, as I did, that the MOVPSL should behave like a MOVPSL. I believed this to be the case and files a trouble report with HP. Will it be address? I know not. However, I'm not one to sit about waiting for HP to fix what I believe to be an OpenVMS Macro bug. What I did was devise a workaround for this problem.

First, what I really only needed was to know the current access mode. This can be had by knowing a bit about the Itanium architecture or, at a minimum, its instruction set. I took a look, using the OpenVMS system analyzer, at the actual code of SYS$PAL_RD_PS routine.


SDA> EXAMINE/INSTRUCTION SYS$PAL_RD_PS;80
{ .mib
SYS$PAL_RD_PS_C: alloc r32 = ar.pfs, 01, 01, 00
mov.i r8 = ar.pfs
nop.b 000000
}
{ .mlx
SYS$PAL_RD_PS_C+00010: mov r11 = r0
movl r9 = E0000000.0000⋮ 0000 ;;
}
{ .mmi
SYS$PAL_RD_PS_C+00020: add r9 = 0064, r9 ;;
ld4 r10 = [r9], 1F4
shr.u r8 = r8, 3E ;;
}
{ .mmi
SYS$PAL_RD_PS_C+00030: cmp4.eq p0, p7 = r0, r10
ld4 r17 = [r9], 004
shladd r8 = r8, 3, r0 ;;
}
{ .mmi
SYS$PAL_RD_PS_C+00040: (p7) add r11 = 0001, r0
ld4 r9 = [r9]
and r17 = 1F, r17 ;;
}
{ .mii
SYS$PAL_RD_PS_C+00050: and r9 = 03, r9
zxt4 r11 = r11 ;;
and r11 = 01, r11 ;;
}
{ .mii
SYS$PAL_RD_PS_C+00060: shladd r11 = r11, 2, r0
shl r17 = r17, 08 ;;
or r9 = r11, r9
}
{ .mmi
SYS$PAL_RD_PS_C+00070: or r8 = r17, r8 ;;
or r8 = r8, r9
nop.i 000000
}
{ .mfb
SYS$PAL_RD_PS_C+00080: nop.m 000000
nop.f 000000
br.ret.sptk.many b0 ;;
}

The second instruction in the first instruction bundle obtains the current privilege mode from the Itanium's PFS (Previous Function State) register. Because this is all I needed, I first tried replacing the MOVPSL in the system service intercept trap routine with:



$IA64REGDEF ; Itanium special register definitions
$PFSDEF ; previous function state definitions



IA64_GETREG R0,#IA64_REG$_AR_PFS ; get previous function state
EVAX_SRL R0,#PFS$V_PPL,R0 ; get previous privilege level
CMPL R0,#PSL$C_USER ; insure access mode is USER

This provided me with what I needed for my system servcie interrupt trap. I compiled and linked the TMESIS DCL Debugger with the above workaround and everyting was, once again, functional. However, I was determined to devise a solution which would allow me to actually use the MOVPSL in the intercept just as it was used for the Alpha and VAX code.

The solution was, remarkably, simple. The system service intercept trap routine needed to check if the reason it was being invokes was because it was servicing a call for SYS$PAL_RD_PS. This is accomplished by checking the value passed as the SS_TRAP$_SSV_PRC argument. Comparing this address with that of the SYS$PAL_RD_PS FD address and leaving the system service intercept trap routine if the values compare is the solution. The completely amended code is:


.LIBRARY "SYS$LIBRARY:LIB.MLB"
$SSIDEF ; System Service Intercept DEFinitions

.PSECT DATA,WRT,NOEXE,5
SSI.BLOCK: .LONG 0[SSI$S_SSI_BLOCK/4]

EDTSHR: .ASCID "EDTSHR"
.ALIGN QUAD
EDT$EDIT: .ASCID "EDT$EDIT"
.ALIGN QUAD
EDT$M_NOJOURNAL:.ASCID "EDT$M_NOJOURNAL"
.ALIGN QUAD
FILENAME: .ASCID "TEST.TXT"

.PSECT CODE,NOWRT,EXE,5
.ENTRY GO,0

CLRL -(SP) ; stack for EDT$M_NOJOURNAL value
PUSHAL (SP)
PUSHAL EDT$M_NOJOURNAL
PUSHAL EDTSHR
CALLS #3,G^LIB$FIND_IMAGE_SYMBOL

CLRL -(SP) ; stack for EDT$EDIT entry address
PUSHAL (SP)
PUSHAL EDT$EDIT
PUSHAL EDTSHR
CALLS #3,G^LIB$FIND_IMAGE_SYMBOL

MOVAL SSI.BLOCK,R0
MOVL #SSI$C_VERSION_QUAD_LIST,SSI$L_VERSION(R0)
MOVAL SSI.PRE_TRAP,SSI$PS_PRE_ROUTINE(R0)
$SSI_DECLARE_INTERCEPT_S ssi_block_ptr = SSI.BLOCK

MOVL (SP)+,R0 ; EDT$EDIT entry address => R0

PUSHAL (SP) ; EDT$M_NOJOURNAL by reference
PUSHL #0
PUSHL #0
PUSHL #0
PUSHAL FILENAME
CALLS #5,(R0)

RET

$OFFDEF SS_TRAP,<-
ARG_PTR,- ; service argument list pointer (quad)
SSV_SYS,- ; service PD/FD (system address space)
SSV_PRC,- ; service PD/FD (process address space)
RET_ADR,- ; return address into SSI trap service
SSI_PTR,- ; address of the original SSI structure
>

.ENTRY SSI.PRE_TRAP,0

MOVAL G^SYS$PAL_RD_PS,R0 ; IA64 MOVPSL is SYS$PAL_RD_PS
CMPL SS_TRAP$_SSV_PRC(AP),R0 ; MOVPSL/SYS$PAL_RD_PS invoked?
BEQL 10$ ; don't puke, leave gracefully.

MOVPSL R0

10$: MOVL #1,R0
RET

.END GO

The above will now be able to use the MOVPSL to get the customary PS and it will allow the use of the PS field definitions in $PSLDEF to extract or test fields of the PS.

While I'm at this, this is not only a problem with the SYS$PAL_RD_PS evoked because of the MOVPSL instruction; this will be a problem if any of the VAX or Alpha buit-ins provided by SWIS are invoked within a system service intercept trap routine. And, this is not just a problem with the Macro compiler. Any high-level language employing a system service intercept via the SSI services will have to contend with this issue if, within the system service intercept trap routine, one of the VAX or Alpha SWIS routines is invoked either directly or via a language specific built-in function.


Comments?


To thwart automated comment SPAM, you must answer this question to post.

Comment moderation is enabled. Your comment(s) will not be visisble until approved.
Remember personal info?
Notify?
Hide email?
All html tags, with the exception of <b> and <i>, will be removed from your comment. You can make links by simply typing the url or email-address.

Calendar

« May 2017 »
Sun Mon Tue Wed Thu Fri Sat
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
 

Meta Information:

Title: MOVPSL — I've a feeling we're not in Kansas anymore!
Date: 12-Jun-2014 11:43
Filed:
Size: 2234 words
Next:   » ssh-ecurity — Part 10…
Prev:   « ssh-ecurity — Part 9:…

Frontpage

Search

Archives

Powered by…