GCC and PDPCLIB on MVS 3.8 and above
------------------------------------
If you want to code in C on MVS (3.8, XA,
OS/390 or above), there is now another option
available, and it is both free and clear
of copyright conditions.
There are two separate parts to this, GCC and
PDPCLIB. They are different products, written
by different people, and with different
licencing restrictions.
GCC itself is subject to GPL and thus you will
have to read the licencing restrictions (COPYING)
regarding that. However, any code of yours that
you get GCC to compile, is still yours. And any
public domain code that you get GCC to compile,
is still public domain.
PDPCLIB itself is public domain, so you can use
it, modify it, sell it, with no strings attached.
Thus, if you use only public domain code, plus
your own copyright code, you can in combination
produce your own copyright executables, with no
legal restrictions other than those you put on
yourself. ie you can sell it, use it in a
commercial environment etc etc, with no strings
attached.
You can actually potentially mix and match
these two things. E.g. GCC could be used
with a different C runtime library other than
PDPCLIB. And PDPCLIB could be used with a
C compiler other than GCC (indeed, it was
originally written for use with C/370, to
produce stand-alone executables, which
aren't able to be produced natively). The
only combination that works "out of the box"
currently though, is GCC combined with PDPCLIB.
This combination is referred to from now on
as "GCCMVS".
Now there are two ways you can obtain GCCMVS.
One is to get an existing user of GCCMVS to
dump the applicable libraries, ie:
PDPCLIB.INCLUDE
PDPCLIB.NCALIB
PDPCLIB.LINKLIB
GCC.PROCLIB
GCC.LINKLIB
GCC.JCL
onto tape, then reload onto your system. The
above libraries are the minimum you need. If
you want the source code and documentation as
well, then get:
PDPCLIB.SOURCE
PDPCLIB.DOC
GCC.SOURCE
GCC.INCLUDE
GCC.DOC
If you have the source code and executables,
you can actually use GCCMVS to recompile
itself, so that you know for sure that you
have source code that matches the executables.
It is usual to do this in 3 stages, see below
for details.
The second way of obtaining GCCMVS is purely
from source code. GCCMVS is simply a patch
of around 150k (zipped) on top of standard GCC 3.2.3.
Standard GCC 3.2.3 can be obtained from
ftp.gnu.org/gnu/gcc/gcc-3.2.3/gcc-3.2.3.tar.bz2
File is dated 2003-04-23 00:00 and is
20,662,887 bytes in size.
The official place to obtain this patch from is:
http://www.spftools.com/downloads/gccmvs.htm
It is expected that the patch will eventually
also end up on David Pitts's web site, which is:
http://www.cozx.com/~dpitts/gcc.html
If you obtain GCCMVS in source code form, then
you need the following tools:
1. patch
2. a c compiler (normally gcc for windows is used,
but you can use c compilers other than gcc).
3. Miscellaneous decompression tools such as bzip2
and tar.
4. CVS
So do the following:
bzip2 -d gcc-3.2.3.tar.bz2
tar xvf gcc-3.2.3.tar
ren gcc-3.2.3 gcc
cd gcc
patch -p 1 <patch.txt
cd gcc (ie now you are in gcc/gcc)
For your information, some of the files in
the gccmvs patch were originally obtained by doing:
./configure --target=i370-ibm-mvs38 --enable-languages=c
but you should NOT do that, otherwise you will
overwrite various working source files with
non-working ones.
Next you need to obtain pdpclib. The official
place to get pdpclib from is:
http://sourceforge.net/projects/pdos
You will need to use CVS to access the source
code.
However, you can get it more conveniently from:
http://www.spftools.com/downloads/gccmvs.htm
You should place pdpclib such that the directory
structure looks like this:
gcc/include
gcc/gcc
gcc/libiberty
pdos/pdpclib
ie "pdos" should be at the same level as "gcc".
"pdos" just needs to be an empty directory besides
"pdpclib". You can extract the pdpclib files
into the "pdpclib" directory.
Then, assuming you are doing this from a DOS
prompt (and you are still in gcc/gcc), go:
compile
which will create an executable called gccmvs.exe.
Then run:
compmvs
(unless you want to use unmodified IFOX on MVS 3.8,
in which case go "compmvs -DUSING_IFOX")
which will generate S/370 assembly code.
Next run:
zipall
which will create several zip files suitable for
uploading to the mainframe. Specifically,
PDPCLIB.INCLUDE
PDPCLIB.SOURCE
PDPCLIB.DOC
GCC.PROCLIB
GCC.SOURCE
GCC.INCLUDE
GCC.DOC
GCC.S (for temporary use only)
GCC.JCL
Example JCL to allocate these datasets can
be found in stage0a.jcl. Note that this will
need to be manually transferred to a
temporary dataset prior to being run.
A thing to note about all JCL is that you need
to define two prefixes, one for GCC datasets
and one for PDPCLIB datasets. These are all
set in proc statements using GCCPREF and PDPPREF.
Thus they all need to be changed, as well as
JOBCARD corrections. One other thing is that
some temporary files are assumed to have been
transferred with a userid of "HERC02". You
should change any occurrence of HERC02 to
something appropriate for your use.
In fact, the following changes will need to
be made to all JCL, and also to gccmvs.prc,
for operation in a 31-bit environment. It is
recommended you use an edit macro to do all
this:
c all IFOX00 ASMA90
c all 'DM2CMP,' 'ST2CMP,'
c all 'DM3CMP,' 'ST3CMP,'
c all 'SYSGO' '*SYSGO'
c all AMODGEN MODGEN
c all 9216K 20M
(this last one can be used to change the whole
jobcard instead)
Now is your big chance to screw things up.
You need to transfer these files with the
same ASCII to EBCDIC translation that GCCMVS
expects. Easiest to stuff up are the following:
| x'4f'
^ x'5f'
[ x'ad'
] x'bd'
If you actually try transferring this file you
are reading now to the mainframe, and do a
search on "screw" and put "hex on", you can
see how successful you are likely to be. There
is a tool called "mvsunzip" supplied as part of
pdpclib which you can use on the mainframe.
Because of the chicken and egg situation, you'll
need to manually upload the pdpclib asm files in
order to create the mvsunzip executable if you want
to make use of this. The JCL, stage0b.jcl is
based on the assumption that you are using that.
Also note that stage0b.jcl will need to be transferred
to a temporary dataset of your own creation
prior to being run.
Now run the JCL from GCC.JCL(STAGE1A) and
GCC.JCL(STAGE1B). This will create an
executable called "STAGE1", which is a working
gccmvs, but compiled via this convoluted process.
Note that a common substitute for this step
is to use an existing C compiler to produce
the stage1 executable.
Next run GCC.JCL(STAGE2A-C). Making use of
the just-compiled STAGE1, it will compile from
source code the entire gccmvs suite, this
time to create an executable called STAGE2.
Next run GCC.JCL(STAGE3A-D). Making use of the
just-compiled STAGE2 (which at this stage is
comprised entirely of mainframe-based gccmvs
code), it will create an executable called
"GCC".
Note that the executables STAGE2 and GCC
should be of identical size.
Copy GCC, GCCREPL into the installation
libraries.
Copy GCC.PROCLIB(GCCMVS) into the installation
libraries and modify it for your site's
requirements.
Congratulations, you now have GCCMVS fully
installed.
You can now compile your own C programs by
running the example jcl found in GCC.JCL(EXAMPLE).
Credits:
Everyone who worked on GCC and in particular
the MVS portions, machine definition etc prior
to David Pitts getting hold of it.
David Pitts for doing the port to OS/390 USS.
Paul Edwards did the port to MVS 3.8.
Phil Roberts for testing & debugging the MVS 3.8 port
Dave Wade for fixing the floating point problem
and for doing the VM/CMS port.
Version:
See version.c for the version number.
Support:
PDPCLIB is separately maintained by Paul Edwards,
and some sort of support may be available there.
Certainly submission of *public domain* (ie NOT
GPL) bug fixes/enhancements are welcome.
However, the GCC side of it is currently unsupported.
If someone would like to pick up the ball and run
with it, don't wait for permission from the gods, just
do it!
Note that Paul Edwards doesn't have access to an
MVS machine (any version), so debugging is normally
done by cut-down dumps, link maps and assembly
listings. The logistics of doing this mean that it
is probably easier to debug any problem yourself.
And limitations are limitations, not bugs. You
will definitely need to make the enhancements
yourself.
You can try going to H390-MVS@yahoogroups.com
to see if anyone there can help.
Technical notes about executables created in
this manner:
1. If you link in the entire C library, you
will have an overhead of about 62k. ie, this
is the approximate size of a "hello, world"
program.
2. The memory requirements (not including the
space for the executable) for a "hello, world"
program are about 80k, assuming the default
stack size of 64k is being used in mvsstart.asm.
When running the program in batch, the REGION=
needs to be set to a minimum of about 137K.
Obviously you should try to be more generous
than this for any real application!
3. PDPCLIB is designed to conform to the ANSI
C89 standard (aka ISO/IEC 9899:1990), and there
are no extensions (like "open", "chmod" etc
found on other operating systems or compilers).
In fact, there are large gaps in the implementation,
e.g. there is no floating point, although programs
that reference one of the standard maths routines
will still link (problem deferred to runtime!).
4. What PDPCLIB on MVS is primarily designed for,
is fast processing of binary, fixed block datasets,
and also for text processing. Or if you want to
write a utility to traverse MVS control blocks, you
can use it for that sort of thing. When operating
on binary, fixed-length records, the path from
fwrite to the "PUT" macro is very short indeed.
5. The files that PDPCLIB operates on do not
have default DCB information (LRECL etc). This
has the advantage that the programs will operate
on datasets of any LRECL, but does have the
downside that you need to specify all the DCB
information in your JCL.
6. The executables that are produced can be run
as both TSO command processor or in batch. The
parameter parsing will handle either method of
invocation.
7. Due to a limitation in pdpclib, the executable
will be linked RMODE 24. Although mallocs will
come from above the line when running AMODE 31.
See mvssupa.asm in pdpclib for more info.
8. PDPCLIB makes no attempt to operate on VSAM
datasets, or anything else outside of bog-standard
sequential files. It will also ignore any attempt
to open a file in update mode, or any attempt to
do random access.
9. The compiler requires even static functions to
be unique within the first 8 characters within a
source file. The compiler should be changed to
drop that requirement, by generating internal
labels such as @@F1234.
10. The compiler generates excessive instructions,
reloading the base register at every single label.
The smarts are already in the code generator to
avoid this, it's just that they're not quite smart
enough, so needed to be disabled!
11. If you want to use unmodified IFOX on MVS 3.8,
a lot of flags have been disabled in order to
not exceed the limit (400) of how many external
variables IFOX can handle. This restriction can
be lifted on MVS/XA and above, and indeed, can be
gotten around on MVS 3.8 too. On the other hand,
you are unlikely to miss the disabled flags too.
To get around the restriction on MVS 3.8, you can
either use an assembler other than IFOX, or get:
http://www.prycroft6.com.au/vs2mods/download/asmxfesd.zip
12. As things currently stand, you can't actually
recompile gccmvs with gccmvs on MVS 3.8 because
some of the source files need more memory. It is
expected that more efficient memory management
routines in pdpclib (specifically the memmgr
code in pdos) would get around this problem.
Also, fixing the excessive base register reloads
in gcc and optimizing the code could also
potentially squeeze enough memory out of MVS 3.8.
13. When opening files of the form dd:pds(member),
"PDS" cannot be a concatenation, it will only go
to the first dataset. Thus, when compiling C
programs, you'll have to do the same thing with
INCLUDE and SYSINCL.
14. This problem has now been rectified.
15. I don't know how to do an iebcopy in order
to change the LRECL from 220 to 80, so
PDPCLIB.INCLUDE is not being allocated with my
preferred lrecl at this time.
16. This problem has now been rectified.
17. It would be good if we could compile the
genxxxx.c files on MVS thus dropping the
requirement of having to run "configure" on
the PC.
18. Compiler bugs bug1.c and bug2.c
19. When importing a new release it is necessary
to allow c-parse.c and tradcif.c to be imported.
These are set to ignore in .cvsignore. It would
be better if bison were available on MVS so that
these files could be generated by the compilation
procedure.
20. When you need to refresh the generated files,
just run configure and make and it will build the
generated files. You can find a list of the
generated files in genfiles.txt. Do a diff on the
files before copying them in as some generated
files we want to keep our own version. The command
to run configure is:
./configure --target=i370-ibm-mvs38 --enable-languages=c --prefix=/phil