• Cross gcc targeting VMS

    From antispam@antispam@fricas.org (Waldek Hebisch) to comp.os.vms on Mon Sep 29 16:17:10 2025
    From Newsgroup: comp.os.vms

    As I wrote in another post I am trying to compile cress gcc targeting
    Alpha VMS. In a sense I am in similar situation as Simon. But
    I think I made some progress and I collected some information.

    First, I think it is worth to be more precise about what is working.
    Typicaly programming languages need a compiler and a support
    library. My tests indicate that compilers proper for all languages
    included in gcc-15, except for D build without errors. Currently
    C++ compiler has trouble, compiling some (many) C++ files leads
    to compliants from assembler.

    Problematic is compilation of support libraries. Currently for me
    runtime support libraries for C, Fortran and Objective C build OK.
    Building C++ runtime library fails due to compiler problem mentioned
    above. Cobol, Go, Modula 2 and Rust runtime libraries have
    C++ runtime library as a dependence, so building those libraries
    fails. I think that I managed to build part of Ada runtime library
    that is written in C, but VMS-specific code in part of Ada runtime
    that is written in Ada is removed from reasonably recent gcc versions
    (this probably happended around gcc-6.5). Worse, current Ada
    backend seem to support only "zero cost exception handing" while
    old VMS port seemed to use setjmp-longjmp exception handing.
    So probably one needs to write some new VMS-specific code to make
    fully working Ada runtime.

    So what works? As I wrote I have my own header files. I also
    wrote a tool to create fake shared libraries. So I have now set
    of libraries that allow linking of C and Fortran programs. Header
    file have substantial gaps, they contain what is needed to build
    gcc runtime but otherwise miss a lot. Fake libraries have slots
    for majority of documented VMS C functions, functions from LIBRTL
    and SYS$PUBLIC_VECTORS. There is also bunch of slots for
    undocumented functions used by gcc. But majority of positions
    in symbol vectors is taken by dummies, so there may be a lot
    missing functions. Concerning missing documented functions:
    some of them apparently are not functions but macros, some may
    use strange renaming tricks. In general each requires specific
    attention to find out what happens.

    I have now preliminary support for _USE_STD_STAT in my header files.
    It uses gcc-specific features (precifically pragma redefine_extname).
    I do not know how DEC/HP/VSI handle the issue, but solution adapted
    in VMS headers almost surely depends on specific compiler extentions
    and needed extention is probably not supported by gcc.

    Using my header files and fake libraries I can compile simple C
    programs and they work on VMS. I also compiled a simple Fortran
    subroutine, calling it from C gives expected effect. ATM I did not
    try other languages, but based on experience in other setups I
    expect that calling code in other languages will work as long as
    that code does not need runtime support.

    Now about troubles. VMS C functions use different name at C level
    and different in libraries. Moreover, while offically function is
    available in "imagelib.olb", actual function is in a different library
    and this library is needed for succesful linking. So, one needs
    to know real name of a given function and teach gcc to use it.
    Fortunately, gcc knows about most VMS C functions. But one may
    need to add newer ones. And some functions (like stat) apparently
    need handling in header files. To create fake libraries I needed
    to know which library defines given function and corresponding
    slot number (this info can be extracted from executables calling
    the function).

    Renaming and GNU compiler/assembler features may cause spurious
    errors: runtimes included in gcc in some cases try to provide
    replacements for missing "standard" functions. But attempts to
    compile a replacement definition for function which is renamed
    leads to assembler error. Such attemps at replacemnt are typically
    due to mismatch between C headers and libraries, one needs to
    make sure that all function which gets renamed are properly
    defined in header files (OK, all that gcc runtimes may want to
    replace).

    Another possible trouble is that in case of missing target features
    gcc runtimes may try to compile alternative implementation needing
    less features. Unfortunatly, alternative implementations may
    easily fail to compile (I observed a few failures of this sort).

    When building Fortran runtime I obseved one case of wrong assembly:
    generated assembly code references (no existiong) register number 63.
    I worked around the problem by loweering optimization level for
    affected function. This is troubling, but not too much: AFAICS
    such error will be reliably detected by assembler (so will not
    lead to wrong object code) and it seem to be rare enough that
    workarounds need only little work.

    Concerning C++, as I wrote C++ compiler depends on creating aliased
    names. There seem to be 3 (or more) cases. One case is data
    aliases, in such case '=' construct seem to work OK. Second
    case are alternative names for functions, here '==' seem to work.
    But apparently there is other case (or cases) where logic
    using '=' for data and '==' for functions fails.

    In case of Fortran essentialy empty program:

    program n
    end

    pulls in substantial part of Fortran runtime and attempting to run
    it leads to failure. VMS message indicates that program is executing
    data, ATM I do not know how it gets there. It seems that trouble
    happens during runtime initialization, but currently I do not know
    which code is run for initialization.
    --
    Waldek Hebisch
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From hb0815@mw40171@mucweb.de to comp.os.vms on Mon Sep 29 22:01:12 2025
    From Newsgroup: comp.os.vms

    On 9/29/25 18:17, Waldek Hebisch wrote:

    Now about troubles. VMS C functions use different name at C level
    and different in libraries. Moreover, while offically function is
    available in "imagelib.olb", actual function is in a different library
    and this library is needed for succesful linking. So, one needs
    to know real name of a given function and teach gcc to use it.

    Yes, for example, printf in the source code is changed to DECC$GXPRINTF
    in the object module. DECC$GXPRINTF is a symbol in the shareable image
    library IMAGELIB.OLB. Symbols in a library must be unique. That explains
    the DECC$ prefix. I don't know what the GX means or where it comes from.
    I also don't know where the mapping/replacement table is.

    IMAGELIB.OLB contains only the symbol and a link to the shareable image.
    The actual code (and data) is in the shareable image, not in a library.
    So if you link using IMAGELIB.OLB you link with DECC$SHR. At least on
    Alpha, the symbol DECC$GXPRINTF is also in STARLET.OLB. By default this
    OLB is not used, by default you dynamically link and not statically. Do
    a link on VMS/Alpha with a map file. In the map you will only see
    DECC$SHR, no STARLET.OLB and no IMAGELIB.OLB.


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From jgd@jgd@cix.co.uk (John Dallman) to comp.os.vms on Mon Sep 29 21:49:40 2025
    From Newsgroup: comp.os.vms

    In article <10bebe4$2m4ru$1@paganini.bofh.team>, antispam@fricas.org
    (Waldek Hebisch) wrote:

    As I wrote in another post I am trying to compile cress gcc
    targeting Alpha VMS. In a sense I am in similar situation as
    Simon. But I think I made some progress and I collected some
    information.

    This is excellent work. I can't make any immediate use of it, but it's
    great to see it happening.

    John
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Craig A. Berry@craigberry@nospam.mac.com to comp.os.vms on Mon Sep 29 16:18:10 2025
    From Newsgroup: comp.os.vms


    On 9/29/25 3:01 PM, hb0815 wrote:
    On 9/29/25 18:17, Waldek Hebisch wrote:

    Now about troubles.-a VMS C functions use different name at C level
    and different in libraries.-a Moreover, while offically function is
    available in "imagelib.olb", actual function is in a different library
    and this library is needed for succesful linking.-a So, one needs
    to know real name of a given function and teach gcc to use it.

    Yes, for example, printf in the source code is changed-a to DECC$GXPRINTF
    in the object module. DECC$GXPRINTF is a symbol in the shareable image library IMAGELIB.OLB. Symbols in a library must be unique. That explains
    the DECC$ prefix. I don't know what the GX means or where it comes from.
    I also don't know where the mapping/replacement table is.

    IMAGELIB.OLB contains only the symbol and a link to the shareable image.
    The actual code (and data) is in the shareable image, not in a library.
    So if you link using IMAGELIB.OLB you link with DECC$SHR. At least on
    Alpha, the symbol DECC$GXPRINTF is also in STARLET.OLB. By default this
    OLB is not used, by default you dynamically link and not statically. Do
    a link on VMS/Alpha with a map file. In the map you will only see
    DECC$SHR, no STARLET.OLB and no IMAGELIB.OLB.

    Surely GXPRINTF knows how to format G_FLOAT numbers and there would be
    other versions for X_FLOAT, D_FLOAT, etc.?
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From antispam@antispam@fricas.org (Waldek Hebisch) to comp.os.vms on Mon Sep 29 21:31:42 2025
    From Newsgroup: comp.os.vms

    hb0815 <mw40171@mucweb.de> wrote:
    On 9/29/25 18:17, Waldek Hebisch wrote:

    Now about troubles. VMS C functions use different name at C level
    and different in libraries. Moreover, while offically function is
    available in "imagelib.olb", actual function is in a different library
    and this library is needed for succesful linking. So, one needs
    to know real name of a given function and teach gcc to use it.

    Yes, for example, printf in the source code is changed to DECC$GXPRINTF
    in the object module. DECC$GXPRINTF is a symbol in the shareable image library IMAGELIB.OLB. Symbols in a library must be unique. That explains
    the DECC$ prefix. I don't know what the GX means or where it comes from.

    gcc renames printf to decc$tprintf. IIUC leading t means printf
    working with T format floats, that is with IEEE floats. G means
    (new ???) VAX floating point format, X means 128-bit long double
    format, so GX prefix may mean using G format doubles and X format
    long doubles. gcc by default uses 64-bit long double, when I
    request 128-bit long double then gcc renames printf to decc$txprintf.

    BTW: I do not know why, but gcc emits names of functions in DECC$SHR.EXE
    in lower case, while math library functions in upper case.

    I also don't know where the mapping/replacement table is.

    gcc has file (starting from root of gcc source tree) gcc/config/vms/vms-crtlmap.map. This file contains list of remaped
    functions and flags giving rules for remaping. Those remapings
    are under control of compiler command line, chosing 64 bit pointers
    causes remaping to 64 bit version of the function. Similarly, there
    are variants for different floating point formats.

    IMAGELIB.OLB contains only the symbol and a link to the shareable image.
    The actual code (and data) is in the shareable image, not in a library.

    Yes.

    So if you link using IMAGELIB.OLB you link with DECC$SHR. At least on
    Alpha, the symbol DECC$GXPRINTF is also in STARLET.OLB. By default this
    OLB is not used, by default you dynamically link and not statically.

    GNU linker always uses both IMAGELIB.OLB and STARLET.OLB, in that
    order. If symbol is found via IMAGELIB.OLB linker will not use
    corresponding symbol from STARLET.OLB, even if present. VMS
    documentation says that default action is the same, but options can
    exclude IMAGELIB.OLB or both IMAGELIB.OLB and STARLET.OLB.

    In fact, some symbols like C$_EXIT1 and LIB$INITIALIZE seem to come from STARLET.OLB, even when other symbols come from shared images.

    Do
    a link on VMS/Alpha with a map file. In the map you will only see
    DECC$SHR, no STARLET.OLB and no IMAGELIB.OLB.

    Yes. I mostly looked at executables as I wanted to see information not
    present in map file, but the result is equivalnet. IIUC STARLET.OLB will
    never show up, debug symbols may point to specific object files but
    not to static library.
    --
    Waldek Hebisch
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From John Reagan@johnrreagan@earthlink.net to comp.os.vms on Mon Sep 29 18:04:03 2025
    From Newsgroup: comp.os.vms

    On 9/29/2025 4:01 PM, hb0815 wrote:
    On 9/29/25 18:17, Waldek Hebisch wrote:

    Now about troubles.-a VMS C functions use different name at C level
    and different in libraries.-a Moreover, while offically function is
    available in "imagelib.olb", actual function is in a different library
    and this library is needed for succesful linking.-a So, one needs
    to know real name of a given function and teach gcc to use it.

    Yes, for example, printf in the source code is changed-a to DECC$GXPRINTF
    in the object module. DECC$GXPRINTF is a symbol in the shareable image library IMAGELIB.OLB. Symbols in a library must be unique. That explains
    the DECC$ prefix. I don't know what the GX means or where it comes from.
    I also don't know where the mapping/replacement table is.

    IMAGELIB.OLB contains only the symbol and a link to the shareable image.
    The actual code (and data) is in the shareable image, not in a library.
    So if you link using IMAGELIB.OLB you link with DECC$SHR. At least on
    Alpha, the symbol DECC$GXPRINTF is also in STARLET.OLB. By default this
    OLB is not used, by default you dynamically link and not statically. Do
    a link on VMS/Alpha with a map file. In the map you will only see
    DECC$SHR, no STARLET.OLB and no IMAGELIB.OLB.


    The CRTL's mapping table is in the CRTL and is read by the compiler.
    The format isn't documented (I think) and contains more than just names.
    It nothing (well, almost nothing) is hard-coded into the compiler.

    There is also the SYS$LIBRARY:DECC$CRTLMAP.EXE file which is just the
    mapping table. The building of the CRTL needs to known which names get
    mapped in the source. Think of case where we are adding a new routine
    to the RTL. The RTL in the build environment doesn't have the routine
    and its mapping table. We need to get it mapped just to build the first
    time.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Mon Sep 29 19:55:02 2025
    From Newsgroup: comp.os.vms

    On 9/29/2025 4:48 PM, John Dallman wrote:
    In article <10bebe4$2m4ru$1@paganini.bofh.team>, antispam@fricas.org
    (Waldek Hebisch) wrote:
    As I wrote in another post I am trying to compile cress gcc
    targeting Alpha VMS. In a sense I am in similar situation as
    Simon. But I think I made some progress and I collected some
    information.

    This is excellent work. I can't make any immediate use of it, but it's
    great to see it happening.

    Yes.

    Very much.

    VMS need people doing something with VMS today - not people
    that "know" what DEC should have done 40 years ago.

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Chris Townley@news@cct-net.co.uk to comp.os.vms on Tue Sep 30 00:58:33 2025
    From Newsgroup: comp.os.vms

    On 30/09/2025 00:55, Arne Vajh|+j wrote:
    On 9/29/2025 4:48 PM, John Dallman wrote:
    In article <10bebe4$2m4ru$1@paganini.bofh.team>, antispam@fricas.org
    (Waldek Hebisch) wrote:
    As I wrote in another post I am trying to compile cress gcc
    targeting Alpha VMS.-a In a sense I am in similar situation as
    Simon.-a But I think I made some progress and I collected some
    information.

    This is excellent work. I can't make any immediate use of it, but it's
    great to see it happening.

    Yes.

    Very much.

    VMS need people doing something with VMS today - not people
    that "know" what DEC should have done 40 years ago.

    Arne


    Perhaps the OP should post a summary on the VSI forum
    --
    Chris
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Mon Sep 29 19:58:51 2025
    From Newsgroup: comp.os.vms

    On 9/29/2025 5:18 PM, Craig A. Berry wrote:
    On 9/29/25 3:01 PM, hb0815 wrote:
    On 9/29/25 18:17, Waldek Hebisch wrote:
    Now about troubles.-a VMS C functions use different name at C level
    and different in libraries.-a Moreover, while offically function is
    available in "imagelib.olb", actual function is in a different library
    and this library is needed for succesful linking.-a So, one needs
    to know real name of a given function and teach gcc to use it.

    Yes, for example, printf in the source code is changed-a to
    DECC$GXPRINTF in the object module. DECC$GXPRINTF is a symbol in the
    shareable image library IMAGELIB.OLB. Symbols in a library must be
    unique. That explains the DECC$ prefix. I don't know what the GX means
    or where it comes from. I also don't know where the mapping/
    replacement table is.

    IMAGELIB.OLB contains only the symbol and a link to the shareable
    image. The actual code (and data) is in the shareable image, not in a
    library. So if you link using IMAGELIB.OLB you link with DECC$SHR. At
    least on Alpha, the symbol DECC$GXPRINTF is also in STARLET.OLB. By
    default this OLB is not used, by default you dynamically link and not
    statically. Do a link on VMS/Alpha with a map file. In the map you
    will only see DECC$SHR, no STARLET.OLB and no IMAGELIB.OLB.

    Surely GXPRINTF knows how to format G_FLOAT numbers and there would be
    other versions for X_FLOAT, D_FLOAT, etc.?

    I believe GXPRINTF means F+G+X.

    (which is a weird combo but C on VMS Alpha does not support H)

    My reason:

    $ type fpp.c
    #include <stdio.h>

    int main()
    {
    float s = 1.0;
    printf("%f\n", s);
    double d = 1.0;
    printf("%f\n", s);
    long double q = 1.0;
    printf("%Lf\n", q);
    return 0;
    }
    $ cc /list /mach /float=d_float /l_double=64 fpp
    $ link fpp
    $ run fpp
    1.000000
    1.000000
    1.000000
    $ sear fpp.lis decc$,printf /match=and
    6B5A4000 00E0 JSR R26, DECC$DPRINTF
    ; R26, R26
    6B5A4000 00F8 JSR R26, DECC$DPRINTF
    ; R26, R26
    6B5A4000 0110 JSR R26, DECC$DPRINTF
    ; R26, R26
    0030 .LINKAGE DECC$DPRINTF
    $ cc /list /mach /float=g_float /l_double=64 fpp
    $ link fpp
    $ run fpp
    1.000000
    1.000000
    1.000000
    $ sear fpp.lis decc$,printf /match=and
    6B5A4000 00E0 JSR R26, DECC$GPRINTF
    ; R26, R26
    6B5A4000 00F8 JSR R26, DECC$GPRINTF
    ; R26, R26
    6B5A4000 0110 JSR R26, DECC$GPRINTF
    ; R26, R26
    0030 .LINKAGE DECC$GPRINTF
    $ cc /list /mach /float=ieee_float /l_double=64 fpp
    $ link fpp
    $ run fpp
    1.000000
    1.000000
    1.000000
    $ sear fpp.lis decc$,printf /match=and
    6B5A4000 00E0 JSR R26, DECC$TPRINTF
    ; R26, R26
    6B5A4000 00F8 JSR R26, DECC$TPRINTF
    ; R26, R26
    6B5A4000 0110 JSR R26, DECC$TPRINTF
    ; R26, R26
    0030 .LINKAGE DECC$TPRINTF
    $ cc /list /mach /float=d_float /l_double=128 fpp
    $ link fpp
    $ run fpp
    1.000000
    1.000000
    1.000000
    $ sear fpp.lis decc$,printf /match=and
    6B5A4000 00E0 JSR R26, DECC$DXPRINTF
    ; R26, R26
    6B5A4000 00F8 JSR R26, DECC$DXPRINTF
    ; R26, R26
    6B5A4000 0120 JSR R26, DECC$DXPRINTF
    ; R26, R26
    0030 .LINKAGE DECC$DXPRINTF
    $ cc /list /mach /float=g_float /l_double=128 fpp
    $ link fpp
    $ run fpp
    1.000000
    1.000000
    1.000000
    $ sear fpp.lis decc$,printf /match=and
    6B5A4000 00E0 JSR R26, DECC$GXPRINTF
    ; R26, R26
    6B5A4000 00F8 JSR R26, DECC$GXPRINTF
    ; R26, R26
    6B5A4000 0120 JSR R26, DECC$GXPRINTF
    ; R26, R26
    0030 .LINKAGE DECC$GXPRINTF
    $ cc /list /mach /float=ieee_float /l_double=128 fpp
    $ link fpp
    $ run fpp
    1.000000
    1.000000
    1.000000
    $ sear fpp.lis decc$,printf /match=and
    6B5A4000 00E0 JSR R26, DECC$TXPRINTF
    ; R26, R26
    6B5A4000 00F8 JSR R26, DECC$TXPRINTF
    ; R26, R26
    6B5A4000 0120 JSR R26, DECC$TXPRINTF
    ; R26, R26
    0030 .LINKAGE DECC$TXPRINTF

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Mon Sep 29 20:01:25 2025
    From Newsgroup: comp.os.vms

    On 9/29/2025 7:58 PM, Chris Townley wrote:
    On 30/09/2025 00:55, Arne Vajh|+j wrote:
    On 9/29/2025 4:48 PM, John Dallman wrote:
    In article <10bebe4$2m4ru$1@paganini.bofh.team>, antispam@fricas.org
    (Waldek Hebisch) wrote:
    As I wrote in another post I am trying to compile cress gcc
    targeting Alpha VMS.-a In a sense I am in similar situation as
    Simon.-a But I think I made some progress and I collected some
    information.

    This is excellent work. I can't make any immediate use of it, but it's
    great to see it happening.

    Yes.

    Very much.

    VMS need people doing something with VMS today - not people
    that "know" what DEC should have done 40 years ago.

    Perhaps the OP should post a summary on the VSI forum

    Yes.

    Either now or when the result is made available.
    OP's choice.

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From hb0815@mw40171@mucweb.de to comp.os.vms on Tue Sep 30 22:42:09 2025
    From Newsgroup: comp.os.vms

    On 9/29/25 23:31, Waldek Hebisch wrote:

    In fact, some symbols like C$_EXIT1 and LIB$INITIALIZE seem to come from STARLET.OLB, even when other symbols come from shared images.

    Because these symbols are not listed in IMAGELIB.OLB. That is, they are
    not defined in any shareable image pointed to from IMAGELIB.OLB.

    C$_EXIT1 is a message code, in DECC terms a globalvalue, and Message
    files aren't shareable images.

    $ ty f.c
    #include <stdio.h>
    globalvalue C$_EXIT1;
    f(){printf("%08x\n",C$_EXIT1);}
    $ cc f
    $ link/map/cross/full f
    $ search f.map C$_EXIT1
    C$_EXIT1 0035A009 C$ERRNO F
    0035A009 C$_EXIT1
    $ search f.map C$ERRNO/lim=1
    C$ERRNO 0 41
    SYS$COMMON:[SYSLIB]STARLET.OLB;6 22-MAY-2017 22:25 Message A01-12
    $ r f
    0035a009
    $ write sys$output f$message("%x0035a009")
    %C-S-NOMSG, Message number 0035A009
    $ set message sys$message:DECC$MSG
    $ write sys$output f$message("%x0035a009")
    %C-S-EXIT1, exit value 1
    $

    As already said, referencing the symbol LIB$INITIALIZE is used to
    include the LIB$INITIALIZE module. The module contains code. For image initialization, the LIB$INITIALIZE code must be part of the generated
    image. That is, the code can only be included from an object library (or
    an object file).

    --- Synchronet 3.21a-Linux NewsLink 1.2