SDL-Hercules-390 / hyperion

The SDL Hercules 4.x Hyperion version of the System/370, ESA/390, and z/Architecture Emulator
Other
240 stars 90 forks source link

LRA instruction causes abend S0D3 if module size is 4K #455

Closed ghost closed 2 years ago

ghost commented 2 years ago

In Hercules 4.4 the LRA instruction causes abend S0D3 if module size is 4K.

In Hercules 4.3 it works.

Works in this version:

HHC01413I Hercules version 4.3.0.10296-SDL-ga4db8213 (4.3.0.10296)
HHC01414I (C) Copyright 1999-2020 by Roger Bowler, Jan Jaeger, and others
HHC01417I ** The SoftDevLabs version of Hercules **
HHC01415I Build date: Nov 27 2020 at 10:51:04
HHC01417I Built with: Microsoft Visual Studio 2008 (MSVC 150030729 1)
HHC01417I Build type: Windows MSVC AMD64 host architecture build

Fails in this version:

HHC01413I Hercules version 4.4.0.10631-SDL-gbf377f63 (4.4.0.10631)
HHC01414I (C) Copyright 1999-2021 by Roger Bowler, Jan Jaeger, and others
HHC01417I ** The SoftDevLabs version of Hercules **
HHC01415I Build date: Dec 18 2021 at 06:29:50
HHC01417I Built with: Microsoft Visual Studio 2008 (MSVC 150030729 1)
HHC01417I Build type: Windows MSVC AMD64 host architecture build

Failure:

HHC00801I Processor CP01: Special-operation exception code 0013 ilc 4
HHC02324I CP01: PSW=0704000080000000 000000000C90000C INST=B120C01A     LRA   2,26(0,12)             load_real_address
HHC02326I CP01: V:000000000C90001A:K:8E=D1A4 A2A340A2 96948540 A385A7A3 0000 Just some text..
HHC02269I CP01: R0=0000000000000064 R1=000000000000003C
HHC02269I CP01: R2=0000000000000040 R3=00000000009D9D64
HHC02269I CP01: R4=00000000009D9D40 R5=00000000009F81A0
HHC02269I CP01: R6=00000000009C0FC8 R7=0000000000F97280
HHC02269I CP01: R8=00000000009FE830 R9=00000000009F84A8
HHC02269I CP01: RA=0000000001DA6A00 RB=0000000000000001
HHC02269I CP01: RC=000000008C900000 RD=0000000000006F60
HHC02269I CP01: RE=0000000080FD5290 RF=0000000000000000
HHC02271I CP01: C0=00800002DF98EE20 C1=000000017FC70007
HHC02271I CP01: C2=000000007D697B40 C3=0000000100C00034
HHC02271I CP01: C4=0000000100000034 C5=000000007EF6AD00
HHC02271I CP01: C6=00000000FE000000 C7=000000017FC70007
HHC02271I CP01: C8=0000000000000000 C9=0000000000000000
HHC02271I CP01: CA=0000000000000000 CB=0000000000000000
HHC02271I CP01: CC=00000000FA1C0EC3 CD=000000017FC70007
HHC02271I CP01: CE=00000000DF8FEF69 CF=000000007F44E138

Test Job....

Step G3 fails, this is where the module size is 4K.

All 3 programs are identical, except for the 'org zlra+nnnn' instruction.

//A1        EXEC ASMACL,PARM.L='AC=1,LIST'
//C.SYSLIB  DD DISP=SHR,DSN=SYS1.MACLIB
//          DD DISP=SHR,DSN=SYS1.MODGEN
//          DD DISP=SHR,DSN=SYSA.MACLIB
//C.SYSIN   DD *
ZLRA     amode 31
ZLRA     rmode ANY
ZLRA     Csect
         bakr  14,0
         lr    12,15
         using  ZLRA,12
*-
         MODESET MODE=SUP,KEY=ZERO
         lra   2,cmdbfr
         MODESET MODE=PROB,KEY=NZERO
*-
         sr    15,15
         pr    ,
*-
cmdbfr   dc    c'Just some text'
         ds    0d
         org   zlra+4080
         dc    a(0)
         END
//L.SYSLMOD  DD DISP=SHR,DSN=SYSA.TEST.LINKLIB(ZLRA)
//G1       EXEC PGM=ZLRA
//STEPLIB  DD DISP=SHR,DSN=SYSA.TEST.LINKLIB
//*
//A2        EXEC ASMACL,PARM.L='AC=1,LIST'
//C.SYSLIB  DD DISP=SHR,DSN=SYS1.MACLIB
//          DD DISP=SHR,DSN=SYS1.MODGEN
//          DD DISP=SHR,DSN=SYSA.MACLIB
//C.SYSIN   DD *
ZLRA     amode 31
ZLRA     rmode ANY
ZLRA     Csect
         bakr  14,0
         lr    12,15
         using  ZLRA,12
*-
         MODESET MODE=SUP,KEY=ZERO
         lra   2,cmdbfr
         MODESET MODE=PROB,KEY=NZERO
*-
         sr    15,15
         pr    ,
*-
cmdbfr   dc    c'Just some text'
         ds    0d
         org   zlra+4200
         dc    a(0)
         END
//L.SYSLMOD  DD DISP=SHR,DSN=SYSA.TEST.LINKLIB(ZLRA)
//G2       EXEC PGM=ZLRA
//STEPLIB  DD DISP=SHR,DSN=SYSA.TEST.LINKLIB
//*
//A3        EXEC ASMACL,PARM.L='AC=1,LIST'
//C.SYSLIB  DD DISP=SHR,DSN=SYS1.MACLIB
//          DD DISP=SHR,DSN=SYS1.MODGEN
//          DD DISP=SHR,DSN=SYSA.MACLIB
//C.SYSIN   DD *
ZLRA     amode 31
ZLRA     rmode ANY
ZLRA     Csect
         bakr  14,0
         lr    12,15
         using  ZLRA,12
*-
         MODESET MODE=SUP,KEY=ZERO
         lra   2,cmdbfr
         MODESET MODE=PROB,KEY=NZERO
*-
         sr    15,15
         pr    ,
*-
cmdbfr   dc    c'Just some text'
         ds    0d
         org   zlra+4090
         dc    a(0)
         END
//L.SYSLMOD  DD DISP=SHR,DSN=SYSA.TEST.LINKLIB(ZLRA)
//G3       EXEC PGM=ZLRA
//STEPLIB  DD DISP=SHR,DSN=SYSA.TEST.LINKLIB

A1 MODULE SIZE (HEX)   00000FF8
A2 MODULE SIZE (HEX)   00001070
A3 MODULE SIZE (HEX)   00001000
Fish-Git commented 2 years ago

What makes you believe Hercules is behaving incorrectly?

According to SA22-7832-12 zArchitecture Principles of Operation for LRA:

For LOAD REAL ADDRESS (LRA, LRAY) in the 24-bit or 31-bit addressing mode, if bits 0-32 of the 64-bit real or absolute address corresponding to the second-operand virtual address are all zeros, bits 32-63 of the real or absolute address are placed in bit positions 32-63 of general register R1, and bits 0-31 of the register remain unchanged. If bits 0-32 of the real address or absolute are not all zeros, a special- operation exception is recognized.

and:

Special Conditions

A special-operation exception is recognized when, for LRA or LRAY in the 24-bit or 31-bit addressing mode, bits 0-32 of the resultant 64-bit real address are not all zeros.

Your PSW indicates 31-bit addressing mode, your residency mode (rmode) for all three tests is ANY, and the instruction is failing due to a Special-operation exception. What leads you to believe that this is incorrect? What leads you to believe Hercules is malfunctioning?

ghost commented 2 years ago

I assume it is down to Hercules as is does not happen in a real machine. I said that the abend did not happen in Herc 4.3. I have since found that it does. Sorry for the confusion. I had a different MAINSIZE. Once I set them to the same value I could reproduce the error in Herc 4.3 too. But yes, it could be down to storage sizes.

However, I forced an abend in version of the program that worked. I loaded R4 with the address and I see:

 lar r2,cmdbuf
 la  r4,cmdbuf
HHC02269I CP03: R2=000000007D574028 
HHC02269I CP03: R4=000000000C900028

In both registers, bits 0-32 are zero, so I would not expect a special operation exception. In any case I would expect the same behavior regardless of the module size.

Fish-Git commented 2 years ago
lar r2,cmdbuf
la  r4,cmdbuf

HHC02269I CP03: R2=000000007D574028 
HHC02269I CP03: R4=000000000C900028

(I presume you meant LRA)

The Principles of Operation manual clearly states:

If bits 0-32 of the real address or absolute are not all zeros, a special-operation exception is recognized.

The value of R4 is immaterial. It is only the real address or absolute address that the virtual address translates to that matters.

If the virtual address translates to a real or absolute address that is larger than 2GB, the real address WON'T FIT in your target register. Addresses larger than 2GB cannot be contained in a 32-bit register when running in 31-bit addressing mode.

In your debug example you provided above, you got lucky. The address translated to a value less than 2GB. The virtual address X'0C900028' in this case translated to real address X'7D574028', which is a value less than 2GB. Thus it worked just fine.

In your original problem report, it failed because the virtual address you were trying to translate to a real address, translated to a value that was greater than 2GB, and therefore could not fit within your 32-bit register. Thus a special operation exception occurred. Your test program was physically loaded at a real storage address above the 2GB line because you specified RMODE ANY. When RMODE ANY is specified, the operating system is free to locate your program anywhere in real storage, and it just happened to choose a location above the 2GB line.

In your second test, you got lucky. The operating system chose to locate your test program at a real address that happened to be below the 2GB line. Thus the LRA instruction was able to complete successfully.

There is nothing wrong with Hercules. Your test programs are bad.

ghost commented 2 years ago

Yes, I did mean LRA. It also abends exactly the same way when linking with RMODE 24. I'll do some more testing.

Fish-Git commented 2 years ago

It also abends exactly the same way when linking with RMODE 24.

That's unexpected!

I'll do some more testing.

Please do. I'm sure you're overlooking something. The LRA instruction hasn't been touched in years, and if there was a bug in it, I doubt ANY z/Architecture operating system would work correctly! It has to be a bug in your program IMHO.

ghost commented 2 years ago

My apologies, I have now seen the abend in a real machine too. It seems to be a moving target, but not down to Hercules.

Fish-Git commented 2 years ago

My apologies, I have now seen the abend in a real machine too.

I suspected as much. I knew it wouldn't necessarily always happen (or always not happen) since whether it does or doesn't happen is ultimately unpredictable given the operating system you're using.

It seems to be a moving target...

Correct. As explained, it all depends on where in storage z/OS decides to load your code (since your rmode was set to "any").

but not down to Hercules.

Yep.   :)

And even though it's now no longer needed (since you've already proven the point for yourself), for completeness I have attached a simple stand-alone test program below that hopefully illustrates what's going on:

What it basically does is execute the LRA instruction for three different virtual addresses, each of which gets translated (via the defined page table) to a different real address: the first to real address 16MB, the second to real address 1GB, and the third to real address 2GB.

The first two succeed without problem, but the third of course always fails due to the resulting real address being >=2GB (which cannot fit in a 32-bit register when in 31-bit addressing mode).

I am closing this issue as Invalid (User Error).


P.S. please don't feel badly about this @WJensen-ITconsult! If you've been involved in programming for any length of time then you should already know that even very skilled and knowledgeable individuals sometimes make silly/stupid mistakes. (I call them brain farts)

Hell, I do it all the freaking time.  ;-)

(Happy holidays everyone!)