• Unix stat on VMS

    From antispam@antispam@fricas.org (Waldek Hebisch) to comp.os.vms on Sun Sep 7 15:03:45 2025
    From Newsgroup: comp.os.vms

    As I wrote I am trying to compile gcc-15 cross-compiler targeting
    VMS. I now have trouble with libgfortran. Namely libgfortran
    tries to use Posix compatiblity to perform some file operations.
    I have trouble with st_ino filed in 'struct stat'. Code below
    ilustrates the problem. I am getting warning from VMS C compiler:

    mp->st_ino = sb.st_ino;
    ....^
    %CC-W-CVTDIFTYPES, In this statement, "sb.st_ino" of type "pointer to unsigned s
    hort", is being converted to "unsigned short".


    mp->st_ino = sb.st_ino;
    .................^
    %CC-W-MAYLOSEDATA, In this statement, "sb.st_ino" has a larger data size than "u
    nsigned short". Assignment can result in data loss.

    While this is only a warning in VMS C, such thing may indicate serious
    problem. Also, I tried to print 'sizeof(sb.st_ino)' and
    'sizeof(unsigned short *)'. The results are 6 and 4 respecitvely.
    So size of type reported above does not match with size of 'sb.st_ino'.

    I am worried by this. And of course important question is if
    'stat' works as described in Posix? I did not check Posix spec,
    but I would expect that ino_t is supposed to be type of 'st_ino'
    field of of 'struct stat', which apparently fails on VMS.
    And fundamental thing: Posix promises that two files are in
    fact the same file if and only if both 'st_dev' field and
    'st_ino' fields match. And libgfortran depends on this.
    Does it hold on VMS?

    ---------------<cut here>----------------------
    #include <sys/stat.h>
    typedef struct
    {
    /* Cached stat(2) values. */
    dev_t st_dev;
    ino_t st_ino;
    long long file_size;
    }
    my_sb;

    int
    my_stat(const char * name, my_sb * mp) {
    struct stat sb;
    int res = stat(name, &sb);
    mp->st_dev = sb.st_dev;
    mp->st_ino = sb.st_ino;
    mp->file_size = sb.st_size;
    return res;
    }
    ---------------<cut here>---------------
    --
    Waldek Hebisch
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Sun Sep 7 11:29:35 2025
    From Newsgroup: comp.os.vms

    On 9/7/2025 11:03 AM, Waldek Hebisch wrote:
    As I wrote I am trying to compile gcc-15 cross-compiler targeting
    VMS. I now have trouble with libgfortran. Namely libgfortran
    tries to use Posix compatiblity to perform some file operations.
    I have trouble with st_ino filed in 'struct stat'. Code below
    ilustrates the problem. I am getting warning from VMS C compiler:

    mp->st_ino = sb.st_ino;
    ....^
    %CC-W-CVTDIFTYPES, In this statement, "sb.st_ino" of type "pointer to unsigned s
    hort", is being converted to "unsigned short".


    mp->st_ino = sb.st_ino;
    .................^
    %CC-W-MAYLOSEDATA, In this statement, "sb.st_ino" has a larger data size than "u
    nsigned short". Assignment can result in data loss.

    While this is only a warning in VMS C, such thing may indicate serious problem. Also, I tried to print 'sizeof(sb.st_ino)' and
    'sizeof(unsigned short *)'. The results are 6 and 4 respecitvely.
    So size of type reported above does not match with size of 'sb.st_ino'.

    #include <sys/stat.h>
    typedef struct
    {
    /* Cached stat(2) values. */
    dev_t st_dev;
    ino_t st_ino;
    long long file_size;
    }
    my_sb;

    int
    my_stat(const char * name, my_sb * mp) {
    struct stat sb;
    int res = stat(name, &sb);
    mp->st_dev = sb.st_dev;
    mp->st_ino = sb.st_ino;
    mp->file_size = sb.st_size;
    return res;
    }

    A VMS FID is 3 words, so 6 bytes seems right.

    stat.h is a nightmare of #ifdef's.

    I can see 2 approaches worth investigating.

    A)

    Change my_sb to:

    __ino16_t st_ino[3];

    and handle the array.

    B)

    Compile with:

    /def="_USE_STD_STAT"

    (then it looks like your code compiles)

    I have no idea if any of them will work in the bigger context.

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Sun Sep 7 17:11:17 2025
    From Newsgroup: comp.os.vms

    In article <109k6sf$3v9m4$1@paganini.bofh.team>,
    Waldek Hebisch <antispam@fricas.org> wrote:
    As I wrote I am trying to compile gcc-15 cross-compiler targeting
    VMS. I now have trouble with libgfortran. Namely libgfortran
    tries to use Posix compatiblity to perform some file operations.
    I have trouble with st_ino filed in 'struct stat'. Code below
    ilustrates the problem. I am getting warning from VMS C compiler:

    mp->st_ino = sb.st_ino;
    ....^
    %CC-W-CVTDIFTYPES, In this statement, "sb.st_ino" of type "pointer to unsigned s
    hort", is being converted to "unsigned short".


    mp->st_ino = sb.st_ino;
    .................^
    %CC-W-MAYLOSEDATA, In this statement, "sb.st_ino" has a larger data size than "u
    nsigned short". Assignment can result in data loss.

    While this is only a warning in VMS C, such thing may indicate serious >problem. Also, I tried to print 'sizeof(sb.st_ino)' and
    'sizeof(unsigned short *)'. The results are 6 and 4 respecitvely.
    So size of type reported above does not match with size of 'sb.st_ino'.

    The error message above is saying that `sb.st_ino` is a pointer;
    specifically, it's a `unsigned short *`, and that you're trying
    to assign it to an unsigned short without indirecting. One
    wonders what, `mp->st_ino = *sb.st_ino;` would do?

    This doesn't look right to me, though. Clearly, file structures
    on VMS do not have an "inode" in the same way that most of them
    do on Unix, but if the field exists in the struct, it would.

    Looking on Eisner, I see this:

    ```
    $ search *.h ino_t

    ****************************** SYS$COMMON:[DECC$LIB.REFERENCE.DECC$RTLDEF]DECC$TYPES.H;2

    typedef unsigned short __ino_t;

    ****************************** SYS$COMMON:[DECC$LIB.REFERENCE.DECC$RTLDEF]DIRENT.H;2

    ** The type ino_t is an _XOPEN_SOURCE extension.
    # ifndef __INO_T
    # define __INO_T
    typedef __ino_t ino_t;
    __ino_t d_ino[3]; /* file serial number (vms-style inode) */

    ****************************** SYS$COMMON:[DECC$LIB.REFERENCE.DECC$RTLDEF]STAT.H;2

    # ifndef __INO_T
    # define __INO_T 1
    typedef __ino_t ino_t;
    __ino_t st_ino[3]; /* 3 words to receive fid */

    ****************************** SYS$COMMON:[DECC$LIB.REFERENCE.DECC$RTLDEF]TYPES.H;2

    #if !defined __INO_T && !defined _DECC_V4_SOURCE
    # define __INO_T 1
    typedef __ino_t ino_t;
    $
    ```

    So `st_ino` is really an _array_; note again the error message,
    which just tells you the type that the compiler is working with
    in the context of this assignment: that pointer type is due to C
    making unadorned array accesses decay into pointers (an
    historical artifact from the B language, where the `[]` syntax
    was used for pointers as well as arrays), so the compiler turned
    `.st_ino` into a pointer for this access and then complained
    that you were assigning its value to an `unsigned short`.

    I am worried by this. And of course important question is if
    'stat' works as described in Posix? I did not check Posix spec,
    but I would expect that ino_t is supposed to be type of 'st_ino'
    field of of 'struct stat', which apparently fails on VMS.

    It is. But on VMS, that type is an array, not a scalar.

    However, POSIX mandates that `ino_t` is defined as an unsigned
    integer type in `sys/types.h`, so VMS violates POSIX in this
    regard. (https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/sys_types.h.html)

    And fundamental thing: Posix promises that two files are in
    fact the same file if and only if both 'st_dev' field and
    'st_ino' fields match. And libgfortran depends on this.
    Does it hold on VMS?

    In what way does libgfortran really depend on that?

    Perhaps start by building just C/C++ and skip Fortran for now?

    - Dan C


    ---------------<cut here>----------------------
    #include <sys/stat.h>
    typedef struct
    {
    /* Cached stat(2) values. */
    dev_t st_dev;
    ino_t st_ino;
    long long file_size;
    }
    my_sb;

    int
    my_stat(const char * name, my_sb * mp) {
    struct stat sb;
    int res = stat(name, &sb);
    mp->st_dev = sb.st_dev;
    mp->st_ino = sb.st_ino;
    mp->file_size = sb.st_size;
    return res;
    }
    ---------------<cut here>---------------


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From antispam@antispam@fricas.org (Waldek Hebisch) to comp.os.vms on Sun Sep 7 18:17:06 2025
    From Newsgroup: comp.os.vms

    Dan Cross <cross@spitfire.i.gajendra.net> wrote:
    In article <109k6sf$3v9m4$1@paganini.bofh.team>,
    Waldek Hebisch <antispam@fricas.org> wrote:
    As I wrote I am trying to compile gcc-15 cross-compiler targeting
    VMS. I now have trouble with libgfortran. Namely libgfortran
    tries to use Posix compatiblity to perform some file operations.
    I have trouble with st_ino filed in 'struct stat'. Code below
    ilustrates the problem. I am getting warning from VMS C compiler:

    mp->st_ino = sb.st_ino;
    ....^
    %CC-W-CVTDIFTYPES, In this statement, "sb.st_ino" of type "pointer to unsigned s
    hort", is being converted to "unsigned short".


    mp->st_ino = sb.st_ino;
    .................^
    %CC-W-MAYLOSEDATA, In this statement, "sb.st_ino" has a larger data size than "u
    nsigned short". Assignment can result in data loss.

    While this is only a warning in VMS C, such thing may indicate serious >>problem. Also, I tried to print 'sizeof(sb.st_ino)' and
    'sizeof(unsigned short *)'. The results are 6 and 4 respecitvely.
    So size of type reported above does not match with size of 'sb.st_ino'.

    The error message above is saying that `sb.st_ino` is a pointer; specifically, it's a `unsigned short *`, and that you're trying
    to assign it to an unsigned short without indirecting. One
    wonders what, `mp->st_ino = *sb.st_ino;` would do?

    This doesn't look right to me, though. Clearly, file structures
    on VMS do not have an "inode" in the same way that most of them
    do on Unix, but if the field exists in the struct, it would.

    Looking on Eisner, I see this:

    ```
    $ search *.h ino_t

    ****************************** SYS$COMMON:[DECC$LIB.REFERENCE.DECC$RTLDEF]DECC$TYPES.H;2

    typedef unsigned short __ino_t;

    ****************************** SYS$COMMON:[DECC$LIB.REFERENCE.DECC$RTLDEF]DIRENT.H;2

    ** The type ino_t is an _XOPEN_SOURCE extension.
    # ifndef __INO_T
    # define __INO_T
    typedef __ino_t ino_t;
    __ino_t d_ino[3]; /* file serial number (vms-style inode) */

    ****************************** SYS$COMMON:[DECC$LIB.REFERENCE.DECC$RTLDEF]STAT.H;2

    # ifndef __INO_T
    # define __INO_T 1
    typedef __ino_t ino_t;
    __ino_t st_ino[3]; /* 3 words to receive fid */

    ****************************** SYS$COMMON:[DECC$LIB.REFERENCE.DECC$RTLDEF]TYPES.H;2

    #if !defined __INO_T && !defined _DECC_V4_SOURCE
    # define __INO_T 1
    typedef __ino_t ino_t;
    $
    ```

    So `st_ino` is really an _array_; note again the error message,
    which just tells you the type that the compiler is working with
    in the context of this assignment: that pointer type is due to C
    making unadorned array accesses decay into pointers (an
    historical artifact from the B language, where the `[]` syntax
    was used for pointers as well as arrays), so the compiler turned
    `.st_ino` into a pointer for this access and then complained
    that you were assigning its value to an `unsigned short`.

    I am worried by this. And of course important question is if
    'stat' works as described in Posix? I did not check Posix spec,
    but I would expect that ino_t is supposed to be type of 'st_ino'
    field of of 'struct stat', which apparently fails on VMS.

    It is. But on VMS, that type is an array, not a scalar.

    However, POSIX mandates that `ino_t` is defined as an unsigned
    integer type in `sys/types.h`, so VMS violates POSIX in this
    regard. (https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/sys_types.h.html)

    Yes, I st_ino on VMS is an array. I have now modified libgfortran
    to accomodate this.

    And fundamental thing: Posix promises that two files are in
    fact the same file if and only if both 'st_dev' field and
    'st_ino' fields match. And libgfortran depends on this.
    Does it hold on VMS?

    In what way does libgfortran really depend on that?

    libgfortran has function which should determine if two files
    are in fact the same file. And it uses Posix features,
    except for MinGW where thay use MinGW-specific method.
    If that Posix feature fail, then correspondig function in
    libgfortran will not work correctly.

    Perhaps start by building just C/C++ and skip Fortran for now?

    Well, C builds OK (I need to do extra work so that generated
    binares have chance of working on VMS). C++ build waits for
    resolution of binutils problems (only gas problem is critical to
    build but probably it will be resolved only after other binutils
    problems are resolved). Ada hits trouble very early (could be
    because host has gcc/GNAT 12). So Fortran is natural place
    to make progress.
    --
    Waldek Hebisch
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Sun Sep 7 19:33:42 2025
    From Newsgroup: comp.os.vms

    In article <109ki70$2fj$1@paganini.bofh.team>,
    Waldek Hebisch <antispam@fricas.org> wrote:
    Dan Cross <cross@spitfire.i.gajendra.net> wrote:
    In article <109k6sf$3v9m4$1@paganini.bofh.team>,
    Waldek Hebisch <antispam@fricas.org> wrote:
    As I wrote I am trying to compile gcc-15 cross-compiler targeting
    VMS. I now have trouble with libgfortran. Namely libgfortran
    tries to use Posix compatiblity to perform some file operations.
    I have trouble with st_ino filed in 'struct stat'. Code below
    ilustrates the problem. I am getting warning from VMS C compiler:

    mp->st_ino = sb.st_ino;
    ....^
    %CC-W-CVTDIFTYPES, In this statement, "sb.st_ino" of type "pointer to unsigned s
    hort", is being converted to "unsigned short".


    mp->st_ino = sb.st_ino;
    .................^
    %CC-W-MAYLOSEDATA, In this statement, "sb.st_ino" has a larger data size than "u
    nsigned short". Assignment can result in data loss.

    While this is only a warning in VMS C, such thing may indicate serious >>>problem. Also, I tried to print 'sizeof(sb.st_ino)' and
    'sizeof(unsigned short *)'. The results are 6 and 4 respecitvely.
    So size of type reported above does not match with size of 'sb.st_ino'.

    The error message above is saying that `sb.st_ino` is a pointer;
    specifically, it's a `unsigned short *`, and that you're trying
    to assign it to an unsigned short without indirecting. One
    wonders what, `mp->st_ino = *sb.st_ino;` would do?

    This doesn't look right to me, though. Clearly, file structures
    on VMS do not have an "inode" in the same way that most of them
    do on Unix, but if the field exists in the struct, it would.

    Looking on Eisner, I see this:

    ```
    $ search *.h ino_t

    ******************************
    SYS$COMMON:[DECC$LIB.REFERENCE.DECC$RTLDEF]DECC$TYPES.H;2

    typedef unsigned short __ino_t;

    ******************************
    SYS$COMMON:[DECC$LIB.REFERENCE.DECC$RTLDEF]DIRENT.H;2

    ** The type ino_t is an _XOPEN_SOURCE extension.
    # ifndef __INO_T
    # define __INO_T
    typedef __ino_t ino_t;
    __ino_t d_ino[3]; /* file serial number (vms-style inode) */

    ******************************
    SYS$COMMON:[DECC$LIB.REFERENCE.DECC$RTLDEF]STAT.H;2

    # ifndef __INO_T
    # define __INO_T 1
    typedef __ino_t ino_t;
    __ino_t st_ino[3]; /* 3 words to receive fid */

    ******************************
    SYS$COMMON:[DECC$LIB.REFERENCE.DECC$RTLDEF]TYPES.H;2

    #if !defined __INO_T && !defined _DECC_V4_SOURCE
    # define __INO_T 1
    typedef __ino_t ino_t;
    $
    ```

    So `st_ino` is really an _array_; note again the error message,
    which just tells you the type that the compiler is working with
    in the context of this assignment: that pointer type is due to C
    making unadorned array accesses decay into pointers (an
    historical artifact from the B language, where the `[]` syntax
    was used for pointers as well as arrays), so the compiler turned
    `.st_ino` into a pointer for this access and then complained
    that you were assigning its value to an `unsigned short`.

    I am worried by this. And of course important question is if
    'stat' works as described in Posix? I did not check Posix spec,
    but I would expect that ino_t is supposed to be type of 'st_ino'
    field of of 'struct stat', which apparently fails on VMS.

    It is. But on VMS, that type is an array, not a scalar.

    However, POSIX mandates that `ino_t` is defined as an unsigned
    integer type in `sys/types.h`, so VMS violates POSIX in this
    regard.
    (https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/sys_types.h.html)

    Yes, I st_ino on VMS is an array. I have now modified libgfortran
    to accomodate this.

    And fundamental thing: Posix promises that two files are in
    fact the same file if and only if both 'st_dev' field and
    'st_ino' fields match. And libgfortran depends on this.
    Does it hold on VMS?

    In what way does libgfortran really depend on that?

    libgfortran has function which should determine if two files
    are in fact the same file. And it uses Posix features,
    except for MinGW where thay use MinGW-specific method.
    If that Posix feature fail, then correspondig function in
    libgfortran will not work correctly.

    Given that there is precedent for specific platforms in that
    code, why not make a VMS-specific variant?

    Perhaps start by building just C/C++ and skip Fortran for now?

    Well, C builds OK (I need to do extra work so that generated
    binares have chance of working on VMS). C++ build waits for
    resolution of binutils problems (only gas problem is critical to
    build but probably it will be resolved only after other binutils
    problems are resolved). Ada hits trouble very early (could be
    because host has gcc/GNAT 12). So Fortran is natural place
    to make progress.

    Ok. I'd bias towards getting C executables working first, but I
    am not the one swinging the hammer here.

    - Dan C.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From antispam@antispam@fricas.org (Waldek Hebisch) to comp.os.vms on Sun Sep 7 20:46:03 2025
    From Newsgroup: comp.os.vms

    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 9/7/2025 11:03 AM, Waldek Hebisch wrote:
    As I wrote I am trying to compile gcc-15 cross-compiler targeting
    VMS. I now have trouble with libgfortran. Namely libgfortran
    tries to use Posix compatiblity to perform some file operations.
    I have trouble with st_ino filed in 'struct stat'. Code below
    ilustrates the problem. I am getting warning from VMS C compiler:

    mp->st_ino = sb.st_ino;
    ....^
    %CC-W-CVTDIFTYPES, In this statement, "sb.st_ino" of type "pointer to unsigned s
    hort", is being converted to "unsigned short".


    mp->st_ino = sb.st_ino;
    .................^
    %CC-W-MAYLOSEDATA, In this statement, "sb.st_ino" has a larger data size than "u
    nsigned short". Assignment can result in data loss.

    While this is only a warning in VMS C, such thing may indicate serious
    problem. Also, I tried to print 'sizeof(sb.st_ino)' and
    'sizeof(unsigned short *)'. The results are 6 and 4 respecitvely.
    So size of type reported above does not match with size of 'sb.st_ino'.

    #include <sys/stat.h>
    typedef struct
    {
    /* Cached stat(2) values. */
    dev_t st_dev;
    ino_t st_ino;
    long long file_size;
    }
    my_sb;

    int
    my_stat(const char * name, my_sb * mp) {
    struct stat sb;
    int res = stat(name, &sb);
    mp->st_dev = sb.st_dev;
    mp->st_ino = sb.st_ino;
    mp->file_size = sb.st_size;
    return res;
    }

    A VMS FID is 3 words, so 6 bytes seems right.

    stat.h is a nightmare of #ifdef's.

    I can see 2 approaches worth investigating.

    A)

    Change my_sb to:

    __ino16_t st_ino[3];

    and handle the array.

    Yes, I did it that way.

    B)

    Compile with:

    /def="_USE_STD_STAT"

    (then it looks like your code compiles)

    I have no idea if any of them will work in the bigger context.

    That looks nice. But ATM I want code to compile using gcc in its
    basic setup, so this is less attractive.
    --
    Waldek Hebisch
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Craig A. Berry@craigberry@nospam.mac.com to comp.os.vms on Sun Sep 7 16:33:03 2025
    From Newsgroup: comp.os.vms

    On 9/7/25 1:17 PM, Waldek Hebisch wrote:
    Dan Cross <cross@spitfire.i.gajendra.net> wrote:
    In article <109k6sf$3v9m4$1@paganini.bofh.team>,
    Waldek Hebisch <antispam@fricas.org> wrote:
    As I wrote I am trying to compile gcc-15 cross-compiler targeting
    VMS. I now have trouble with libgfortran. Namely libgfortran
    tries to use Posix compatiblity to perform some file operations.
    I have trouble with st_ino filed in 'struct stat'. Code below
    ilustrates the problem. I am getting warning from VMS C compiler:

    mp->st_ino = sb.st_ino;
    ....^
    %CC-W-CVTDIFTYPES, In this statement, "sb.st_ino" of type "pointer to unsigned s
    hort", is being converted to "unsigned short".


    mp->st_ino = sb.st_ino;
    .................^
    %CC-W-MAYLOSEDATA, In this statement, "sb.st_ino" has a larger data size than "u
    nsigned short". Assignment can result in data loss.

    While this is only a warning in VMS C, such thing may indicate serious
    problem. Also, I tried to print 'sizeof(sb.st_ino)' and
    'sizeof(unsigned short *)'. The results are 6 and 4 respecitvely.
    So size of type reported above does not match with size of 'sb.st_ino'.

    The error message above is saying that `sb.st_ino` is a pointer;
    specifically, it's a `unsigned short *`, and that you're trying
    to assign it to an unsigned short without indirecting. One
    wonders what, `mp->st_ino = *sb.st_ino;` would do?

    This doesn't look right to me, though. Clearly, file structures
    on VMS do not have an "inode" in the same way that most of them
    do on Unix, but if the field exists in the struct, it would.

    Looking on Eisner, I see this:

    ```
    $ search *.h ino_t

    ******************************
    SYS$COMMON:[DECC$LIB.REFERENCE.DECC$RTLDEF]DECC$TYPES.H;2

    typedef unsigned short __ino_t;

    ******************************
    SYS$COMMON:[DECC$LIB.REFERENCE.DECC$RTLDEF]DIRENT.H;2

    ** The type ino_t is an _XOPEN_SOURCE extension.
    # ifndef __INO_T
    # define __INO_T
    typedef __ino_t ino_t;
    __ino_t d_ino[3]; /* file serial number (vms-style inode) */

    ******************************
    SYS$COMMON:[DECC$LIB.REFERENCE.DECC$RTLDEF]STAT.H;2

    # ifndef __INO_T
    # define __INO_T 1
    typedef __ino_t ino_t;
    __ino_t st_ino[3]; /* 3 words to receive fid */

    ******************************
    SYS$COMMON:[DECC$LIB.REFERENCE.DECC$RTLDEF]TYPES.H;2

    #if !defined __INO_T && !defined _DECC_V4_SOURCE
    # define __INO_T 1
    typedef __ino_t ino_t;
    $
    ```

    So `st_ino` is really an _array_; note again the error message,
    which just tells you the type that the compiler is working with
    in the context of this assignment: that pointer type is due to C
    making unadorned array accesses decay into pointers (an
    historical artifact from the B language, where the `[]` syntax
    was used for pointers as well as arrays), so the compiler turned
    `.st_ino` into a pointer for this access and then complained
    that you were assigning its value to an `unsigned short`.

    I am worried by this. And of course important question is if
    'stat' works as described in Posix? I did not check Posix spec,
    but I would expect that ino_t is supposed to be type of 'st_ino'
    field of of 'struct stat', which apparently fails on VMS.

    It is. But on VMS, that type is an array, not a scalar.

    However, POSIX mandates that `ino_t` is defined as an unsigned
    integer type in `sys/types.h`, so VMS violates POSIX in this
    regard.
    (https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/sys_types.h.html)

    Yes, I st_ino on VMS is an array. I have now modified libgfortran
    to accomodate this.

    Yes and no. If you insist on using decades-old VAX C compatibility
    features, then st_ino is an array. Probably because you couldn't fit 3
    words into any integral type on VAX.

    If you define _USE_STD_STAT, though, then you get:

    typedef unsigned __int64 __ino_t;
    typedef __ino_t ino_t;

    You also get large file support, which you could get independently via _LARGEFILE if for some reason you had to. You definitely want
    _USE_STD_STAT for anything new and/or cross-platform. That gets you
    something that was POSIX-compliant a decade or two ago. It isn't
    compliant now because the file times are still just ints rather than
    structs with high-precision components as newer POSIX requires.
    And fundamental thing: Posix promises that two files are in
    fact the same file if and only if both 'st_dev' field and
    'st_ino' fields match. And libgfortran depends on this.
    Does it hold on VMS?
    If st_ino is an integral type, then I think the answer is yes. If it's
    the array type, then it probably depends on who's doing the comparisons.
    If you pass the stat structure to existing code that does the
    comparison, it may or may not handle the array correctly.

    Perl has bent over backwards to try to get around this very ino_t problem:

    <https://github.com/Perl/perl5/blob/feb2c501977cb47f91dc5fc057341dc3f793cc86/vms/vmsish.h#L546>

    I'm not saying you want to do the same thing (in fact really hope you
    don't) but the comments there may illustrate the mess you have to wade
    through if you try to avoid using a slightly more modern stat struct.


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.os.vms on Sun Sep 7 21:52:06 2025
    From Newsgroup: comp.os.vms

    On Sun, 7 Sep 2025 16:33:03 -0500, Craig A. Berry wrote:

    You definitely want _USE_STD_STAT for anything new and/or
    cross-platform.

    CanrCOt find that in any file in /usr/include on my Debian system.

    That gets you something that was POSIX-compliant a decade or two
    ago. It isn't compliant now because the file times are still just
    ints rather than structs with high-precision components as newer
    POSIX requires.

    longs rather than ints. From /usr/include/asm-generic/stat.h:

    struct stat {
    ...
    unsigned long st_ino; /* File serial number. */
    ...
    long st_atime; /* Time of last access. */
    unsigned long st_atime_nsec;
    long st_mtime; /* Time of last modification. */
    unsigned long st_mtime_nsec;
    long st_ctime; /* Time of last status change. */
    unsigned long st_ctime_nsec;
    ...
    };

    I thought it would be time_t ...

    ... Ah, I see, there is a man page stat(3type) which documents the
    time fields as structs and st_ino as of type ino_t, as you describe.
    The layout is compatible with the include file above, of course. CanrCOt
    find any actual include file that defines it that way.

    ... Yes I can: itrCOs /usr/include/-2arch-triple-+/bits/struct_stat.h.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Sun Sep 7 18:46:12 2025
    From Newsgroup: comp.os.vms

    On 9/7/2025 5:33 PM, Craig A. Berry wrote:
    Waldek Hebisch <antispam@fricas.org> wrote:
    And fundamental thing: Posix promises that two files are in
    fact the same file if and only if both 'st_dev' field and
    'st_ino' fields match.-a And libgfortran depends on this.
    Does it hold on VMS?
    If st_ino is an integral type, then I think the answer is yes.-a If it's
    the array type, then it probably depends on who's doing the comparisons.
    If you pass the stat structure to existing code that does the
    comparison, it may or may not handle the array correctly.

    I believe it contains FID.

    Same disk and same FID must mean same file.

    Different file must mean either different disk or different FID.

    So either 3 comparisons of int16_t or one comparison of int64_t
    should do it. Assuming that the last 16 bit of the int64_t always
    has same value (like 0).

    Arne


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Craig A. Berry@craigberry@nospam.mac.com to comp.os.vms on Sun Sep 7 17:55:35 2025
    From Newsgroup: comp.os.vms


    On 9/7/25 5:46 PM, Arne Vajh|+j wrote:
    On 9/7/2025 5:33 PM, Craig A. Berry wrote:
    Waldek Hebisch <antispam@fricas.org> wrote:
    And fundamental thing: Posix promises that two files are in
    fact the same file if and only if both 'st_dev' field and
    'st_ino' fields match.-a And libgfortran depends on this.
    Does it hold on VMS?
    If st_ino is an integral type, then I think the answer is yes.-a If it's
    the array type, then it probably depends on who's doing the comparisons.
    If you pass the stat structure to existing code that does the
    comparison, it may or may not handle the array correctly.

    I believe it contains FID.

    Same disk and same FID must mean same file.

    Different file must mean either different disk or different FID.

    So either 3 comparisons of int16_t or one comparison of int64_t
    should do it. Assuming that the last 16 bit of the int64_t always
    has same value (like 0).

    Right, so you do something like the following, and then have to make
    sure that everything everywhere uses only the macros for doing the
    comparisons:

    #if defined(_USE_STD_STAT) || defined(_LARGEFILE)
    #define VMS_INO_T_COMPARE(__a, __b) (__a != __b)
    #define VMS_INO_T_COPY(__a, __b) __a = __b
    #else
    #define VMS_INO_T_COMPARE(__a, __b) memcmp(&__a, &__b, 6)
    #define VMS_INO_T_COPY(__a, __b) memcpy(&__a, &__b, 6)
    #endif
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Simon Clubley@clubley@remove_me.eisner.decus.org-Earth.UFP to comp.os.vms on Mon Sep 8 12:32:01 2025
    From Newsgroup: comp.os.vms

    On 2025-09-07, Waldek Hebisch <antispam@fricas.org> wrote:

    Well, C builds OK (I need to do extra work so that generated
    binares have chance of working on VMS). C++ build waits for
    resolution of binutils problems (only gas problem is critical to
    build but probably it will be resolved only after other binutils
    problems are resolved). Ada hits trouble very early (could be
    because host has gcc/GNAT 12). So Fortran is natural place
    to make progress.


    Well, for motivation, a simple C program built on Linux using
    cross compiled gcc/binutils worked just fine on Alpha VMS for me. :-)
    It's the one bit I did get working.

    I wish you well with Fortran. If you do get it working, I would
    be interested in you posting here what you had to do to get it
    to generate executables that run OK on VMS.

    Simon.
    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From antispam@antispam@fricas.org (Waldek Hebisch) to comp.os.vms on Tue Sep 9 02:05:40 2025
    From Newsgroup: comp.os.vms

    Craig A. Berry <craigberry@nospam.mac.com> wrote:
    On 9/7/25 1:17 PM, Waldek Hebisch wrote:
    Dan Cross <cross@spitfire.i.gajendra.net> wrote:
    In article <109k6sf$3v9m4$1@paganini.bofh.team>,
    Waldek Hebisch <antispam@fricas.org> wrote:
    As I wrote I am trying to compile gcc-15 cross-compiler targeting
    VMS. I now have trouble with libgfortran. Namely libgfortran
    tries to use Posix compatiblity to perform some file operations.
    I have trouble with st_ino filed in 'struct stat'. Code below
    ilustrates the problem. I am getting warning from VMS C compiler:

    mp->st_ino = sb.st_ino;
    ....^
    %CC-W-CVTDIFTYPES, In this statement, "sb.st_ino" of type "pointer to unsigned s
    hort", is being converted to "unsigned short".


    mp->st_ino = sb.st_ino;
    .................^
    %CC-W-MAYLOSEDATA, In this statement, "sb.st_ino" has a larger data size than "u
    nsigned short". Assignment can result in data loss.

    While this is only a warning in VMS C, such thing may indicate serious >>>> problem. Also, I tried to print 'sizeof(sb.st_ino)' and
    'sizeof(unsigned short *)'. The results are 6 and 4 respecitvely.
    So size of type reported above does not match with size of 'sb.st_ino'. >>>
    The error message above is saying that `sb.st_ino` is a pointer;
    specifically, it's a `unsigned short *`, and that you're trying
    to assign it to an unsigned short without indirecting. One
    wonders what, `mp->st_ino = *sb.st_ino;` would do?

    This doesn't look right to me, though. Clearly, file structures
    on VMS do not have an "inode" in the same way that most of them
    do on Unix, but if the field exists in the struct, it would.

    Looking on Eisner, I see this:

    ```
    $ search *.h ino_t

    ******************************
    SYS$COMMON:[DECC$LIB.REFERENCE.DECC$RTLDEF]DECC$TYPES.H;2

    typedef unsigned short __ino_t;

    ******************************
    SYS$COMMON:[DECC$LIB.REFERENCE.DECC$RTLDEF]DIRENT.H;2

    ** The type ino_t is an _XOPEN_SOURCE extension.
    # ifndef __INO_T
    # define __INO_T
    typedef __ino_t ino_t;
    __ino_t d_ino[3]; /* file serial number (vms-style inode) */

    ******************************
    SYS$COMMON:[DECC$LIB.REFERENCE.DECC$RTLDEF]STAT.H;2

    # ifndef __INO_T
    # define __INO_T 1
    typedef __ino_t ino_t;
    __ino_t st_ino[3]; /* 3 words to receive fid */

    ******************************
    SYS$COMMON:[DECC$LIB.REFERENCE.DECC$RTLDEF]TYPES.H;2

    #if !defined __INO_T && !defined _DECC_V4_SOURCE
    # define __INO_T 1
    typedef __ino_t ino_t;
    $
    ```

    So `st_ino` is really an _array_; note again the error message,
    which just tells you the type that the compiler is working with
    in the context of this assignment: that pointer type is due to C
    making unadorned array accesses decay into pointers (an
    historical artifact from the B language, where the `[]` syntax
    was used for pointers as well as arrays), so the compiler turned
    `.st_ino` into a pointer for this access and then complained
    that you were assigning its value to an `unsigned short`.

    I am worried by this. And of course important question is if
    'stat' works as described in Posix? I did not check Posix spec,
    but I would expect that ino_t is supposed to be type of 'st_ino'
    field of of 'struct stat', which apparently fails on VMS.

    It is. But on VMS, that type is an array, not a scalar.

    However, POSIX mandates that `ino_t` is defined as an unsigned
    integer type in `sys/types.h`, so VMS violates POSIX in this
    regard.
    (https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/sys_types.h.html)

    Yes, I st_ino on VMS is an array. I have now modified libgfortran
    to accomodate this.

    Yes and no. If you insist on using decades-old VAX C compatibility
    features, then st_ino is an array. Probably because you couldn't fit 3
    words into any integral type on VAX.

    If you define _USE_STD_STAT, though, then you get:

    typedef unsigned __int64 __ino_t;
    typedef __ino_t ino_t;

    You also get large file support, which you could get independently via _LARGEFILE if for some reason you had to. You definitely want
    _USE_STD_STAT for anything new and/or cross-platform. That gets you something that was POSIX-compliant a decade or two ago. It isn't
    compliant now because the file times are still just ints rather than
    structs with high-precision components as newer POSIX requires.

    Well, the contex is libgfortran, part of Fortran compiler. It is
    supposed to work with 60 years old Fortran code. Such code may need compatiblity features.

    ATM I did not look if/how gcc supports such switches. This is
    certainly thing to look at later, but now I want old stuff to
    work, when this works I can look at newer things.

    And fundamental thing: Posix promises that two files are in
    fact the same file if and only if both 'st_dev' field and
    'st_ino' fields match. And libgfortran depends on this.
    Does it hold on VMS?
    If st_ino is an integral type, then I think the answer is yes. If it's
    the array type, then it probably depends on who's doing the comparisons.
    If you pass the stat structure to existing code that does the
    comparison, it may or may not handle the array correctly.

    Perl has bent over backwards to try to get around this very ino_t problem:

    <https://github.com/Perl/perl5/blob/feb2c501977cb47f91dc5fc057341dc3f793cc86/vms/vmsish.h#L546>

    I'm not saying you want to do the same thing (in fact really hope you
    don't) but the comments there may illustrate the mess you have to wade through if you try to avoid using a slightly more modern stat struct.


    --
    Waldek Hebisch
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Craig A. Berry@craigberry@nospam.mac.com to comp.os.vms on Tue Sep 9 07:03:58 2025
    From Newsgroup: comp.os.vms


    On 9/8/25 9:05 PM, Waldek Hebisch wrote:
    Craig A. Berry <craigberry@nospam.mac.com> wrote:
    On 9/7/25 1:17 PM, Waldek Hebisch wrote:

    Yes, I st_ino on VMS is an array. I have now modified libgfortran
    to accomodate this.

    Yes and no. If you insist on using decades-old VAX C compatibility
    features, then st_ino is an array. Probably because you couldn't fit 3
    words into any integral type on VAX.

    If you define _USE_STD_STAT, though, then you get:

    typedef unsigned __int64 __ino_t;
    typedef __ino_t ino_t;

    You also get large file support, which you could get independently via
    _LARGEFILE if for some reason you had to. You definitely want
    _USE_STD_STAT for anything new and/or cross-platform. That gets you
    something that was POSIX-compliant a decade or two ago. It isn't
    compliant now because the file times are still just ints rather than
    structs with high-precision components as newer POSIX requires.

    Well, the contex is libgfortran, part of Fortran compiler. It is
    supposed to work with 60 years old Fortran code. Such code may need compatiblity features.

    I'm not sure I follow; that sounds like a conflation of compiler build
    time and compiler run time (user source build time) requirements.

    ATM I did not look if/how gcc supports such switches. This is
    certainly thing to look at later, but now I want old stuff to
    work, when this works I can look at newer things.
    Assuming you've copied the VMS headers over to Linux where you are
    building the compiler, the switch would just be -D_USE_STD_STAT.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Simon Clubley@clubley@remove_me.eisner.decus.org-Earth.UFP to comp.os.vms on Tue Sep 9 12:27:06 2025
    From Newsgroup: comp.os.vms

    On 2025-09-09, Craig A. Berry <craigberry@nospam.mac.com> wrote:

    On 9/8/25 9:05 PM, Waldek Hebisch wrote:
    ATM I did not look if/how gcc supports such switches. This is
    certainly thing to look at later, but now I want old stuff to
    work, when this works I can look at newer things.
    Assuming you've copied the VMS headers over to Linux where you are
    building the compiler, the switch would just be -D_USE_STD_STAT.

    Copying the headers is what I did (with patches afterwards IIRC).
    Waldek OTOH said that he was creating his own headers. I don't know
    if that is still the case.

    BTW, according to the messages I posted at the time, Waldek's C++
    build failure is identical to the one I experienced so clearly
    nothing has changed in this area since then.

    Simon.
    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Tue Sep 9 16:26:45 2025
    From Newsgroup: comp.os.vms

    In article <109o21i$g12m$1@paganini.bofh.team>,
    Waldek Hebisch <antispam@fricas.org> wrote:
    Craig A. Berry <craigberry@nospam.mac.com> wrote:
    On 9/7/25 1:17 PM, Waldek Hebisch wrote:
    [snip]
    Yes, I st_ino on VMS is an array. I have now modified libgfortran
    to accomodate this.

    Yes and no. If you insist on using decades-old VAX C compatibility
    features, then st_ino is an array. Probably because you couldn't fit 3
    words into any integral type on VAX.

    If you define _USE_STD_STAT, though, then you get:

    typedef unsigned __int64 __ino_t;
    typedef __ino_t ino_t;

    You also get large file support, which you could get independently via
    _LARGEFILE if for some reason you had to. You definitely want
    _USE_STD_STAT for anything new and/or cross-platform. That gets you
    something that was POSIX-compliant a decade or two ago. It isn't
    compliant now because the file times are still just ints rather than
    structs with high-precision components as newer POSIX requires.

    Well, the contex is libgfortran, part of Fortran compiler. It is
    supposed to work with 60 years old Fortran code. Such code may need >compatiblity features.

    This gets back to my original question: not all code in
    libgfortran is created the same. I doubt that 60-year old code
    cares about doing inode number+device equality to determine
    uniqueness of a file on a Unix system...particularly as Unix did
    not exist 60 years ago.

    Some code _may_ need that. My guess is that 99.99% wouldn't
    care and you can hack it for now to make forward progress.

    ATM I did not look if/how gcc supports such switches. This is
    certainly thing to look at later, but now I want old stuff to
    work, when this works I can look at newer things.

    You'd just add `-D_USE_STD_STAT` as an additional compiler
    argument when building libgfortran, no?

    - Dan C.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From antispam@antispam@fricas.org (Waldek Hebisch) to comp.os.vms on Tue Sep 9 17:25:47 2025
    From Newsgroup: comp.os.vms

    Simon Clubley <clubley@remove_me.eisner.decus.org-earth.ufp> wrote:
    On 2025-09-09, Craig A. Berry <craigberry@nospam.mac.com> wrote:

    On 9/8/25 9:05 PM, Waldek Hebisch wrote:
    ATM I did not look if/how gcc supports such switches. This is
    certainly thing to look at later, but now I want old stuff to
    work, when this works I can look at newer things.
    Assuming you've copied the VMS headers over to Linux where you are
    building the compiler, the switch would just be -D_USE_STD_STAT.

    Copying the headers is what I did (with patches afterwards IIRC).
    Waldek OTOH said that he was creating his own headers. I don't know
    if that is still the case.

    I am using my own headers and my own (fake) libraries. Because
    may fakes are static libraries the resulting binary has no
    chance of working. I need to work out how to generate fake
    shared images, then binaries linked to fake libraries when
    transfed to VMS will use real libraries from the system and should
    work.

    BTW, according to the messages I posted at the time, Waldek's C++
    build failure is identical to the one I experienced so clearly
    nothing has changed in this area since then.

    I have now fix or workaround for this issue, so build goes further.
    But I get different assembler error at later stage.
    --
    Waldek Hebisch
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Tue Sep 9 14:37:15 2025
    From Newsgroup: comp.os.vms

    On 9/9/2025 12:26 PM, Dan Cross wrote:
    In article <109o21i$g12m$1@paganini.bofh.team>,
    Waldek Hebisch <antispam@fricas.org> wrote:
    Craig A. Berry <craigberry@nospam.mac.com> wrote:
    On 9/7/25 1:17 PM, Waldek Hebisch wrote:
    [snip]
    Yes, I st_ino on VMS is an array. I have now modified libgfortran
    to accomodate this.

    Yes and no. If you insist on using decades-old VAX C compatibility
    features, then st_ino is an array. Probably because you couldn't fit 3
    words into any integral type on VAX.

    If you define _USE_STD_STAT, though, then you get:

    typedef unsigned __int64 __ino_t;
    typedef __ino_t ino_t;

    You also get large file support, which you could get independently via
    _LARGEFILE if for some reason you had to. You definitely want
    _USE_STD_STAT for anything new and/or cross-platform. That gets you
    something that was POSIX-compliant a decade or two ago. It isn't
    compliant now because the file times are still just ints rather than
    structs with high-precision components as newer POSIX requires.

    Well, the contex is libgfortran, part of Fortran compiler. It is
    supposed to work with 60 years old Fortran code. Such code may need
    compatiblity features.

    This gets back to my original question: not all code in
    libgfortran is created the same. I doubt that 60-year old code
    cares about doing inode number+device equality to determine
    uniqueness of a file on a Unix system...particularly as Unix did
    not exist 60 years ago.

    Some code _may_ need that. My guess is that 99.99% wouldn't
    care and you can hack it for now to make forward progress.

    I suspect it is a standard compliance thing.

    Fortran 77 standard says about open:

    <quote>
    If the file to be connected to the unit is not the same as the file to
    which the unit is
    connected, the effect is as if a CLOSE statement (12.10.2) without a
    STATUS= specifier
    had been executed for the unit immediately prior to the execution of the
    OPEN statement.
    If the file to be connected to the unit is the same as the file to which
    the unit is connected,
    only the BLANK= specifier may have a value different from the one
    currently in effect.
    Execution of the OPEN statement causes the new value of the BLANK=
    specifier to be in
    effect. The position of the file is unaffected.
    </quote>

    Fortran 2018 standard says practically the same just with
    more words.

    Demo on VMS:

    $ type f1.txt
    1
    2
    3
    $ type f2.txt
    1
    2
    3
    $ type f.for
    program f
    character*80 line
    open(unit=1,file='f1.txt',status='old')
    read(unit=1,fmt=*) line
    write(*,*) line
    open(unit=1,file='f1.txt',status='old')
    read(unit=1,fmt=*) line
    write(*,*) line
    open(unit=1,file='f2.txt',status='old')
    read(unit=1,fmt=*) line
    write(*,*) line
    end
    $ for f
    $ link f
    $ run f
    1
    2
    1

    It also works with GFortran.

    One can say that the code is pretty hopeless, but standard
    compliance is a real thing.

    Arne



    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Tue Sep 9 19:10:22 2025
    From Newsgroup: comp.os.vms

    In article <109ps4q$153je$1@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 9/9/2025 12:26 PM, Dan Cross wrote:
    In article <109o21i$g12m$1@paganini.bofh.team>,
    Waldek Hebisch <antispam@fricas.org> wrote:
    [snip]
    Well, the contex is libgfortran, part of Fortran compiler. It is
    supposed to work with 60 years old Fortran code. Such code may need
    compatiblity features.

    This gets back to my original question: not all code in
    libgfortran is created the same. I doubt that 60-year old code
    cares about doing inode number+device equality to determine
    uniqueness of a file on a Unix system...particularly as Unix did
    not exist 60 years ago.

    Some code _may_ need that. My guess is that 99.99% wouldn't
    care and you can hack it for now to make forward progress.

    I suspect it is a standard compliance thing.

    Fortran 77 standard says about open:

    <quote>
    If the file to be connected to the unit is not the same as the file to
    which the unit is connected....

    Aha. That's a good reason, then; but in that case, the easiest
    solution is probably to build libgfortran with `-D_USE_STD_STAT`
    or write a VMS-specific implementation for this functionality.

    - Dan C.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From antispam@antispam@fricas.org (Waldek Hebisch) to comp.os.vms on Wed Sep 10 10:48:51 2025
    From Newsgroup: comp.os.vms

    Dan Cross <cross@spitfire.i.gajendra.net> wrote:
    In article <109o21i$g12m$1@paganini.bofh.team>,
    Waldek Hebisch <antispam@fricas.org> wrote:
    Craig A. Berry <craigberry@nospam.mac.com> wrote:
    On 9/7/25 1:17 PM, Waldek Hebisch wrote:
    [snip]
    Yes, I st_ino on VMS is an array. I have now modified libgfortran
    to accomodate this.

    Yes and no. If you insist on using decades-old VAX C compatibility
    features, then st_ino is an array. Probably because you couldn't fit 3
    words into any integral type on VAX.

    If you define _USE_STD_STAT, though, then you get:

    typedef unsigned __int64 __ino_t;
    typedef __ino_t ino_t;

    You also get large file support, which you could get independently via
    _LARGEFILE if for some reason you had to. You definitely want
    _USE_STD_STAT for anything new and/or cross-platform. That gets you
    something that was POSIX-compliant a decade or two ago. It isn't
    compliant now because the file times are still just ints rather than
    structs with high-precision components as newer POSIX requires.

    Well, the contex is libgfortran, part of Fortran compiler. It is
    supposed to work with 60 years old Fortran code. Such code may need >>compatiblity features.

    This gets back to my original question: not all code in
    libgfortran is created the same. I doubt that 60-year old code
    cares about doing inode number+device equality to determine
    uniqueness of a file on a Unix system...particularly as Unix did
    not exist 60 years ago.

    Some code _may_ need that. My guess is that 99.99% wouldn't
    care and you can hack it for now to make forward progress.

    ATM I have single unconditional setup. I made progress,
    after changing 'st_ino' in header file be an array and
    small change to gfortran sources gfortran build works.

    ATM I did not look if/how gcc supports such switches. This is
    certainly thing to look at later, but now I want old stuff to
    work, when this works I can look at newer things.

    You'd just add `-D_USE_STD_STAT` as an additional compiler
    argument when building libgfortran, no?

    Unfortunately, within GCC build this is "hard way". Options
    are set by configure machinery and this is brittle and time
    consuming to test. Comparatively, changes to source files
    are easy.
    --
    Waldek Hebisch
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From antispam@antispam@fricas.org (Waldek Hebisch) to comp.os.vms on Wed Sep 10 11:56:03 2025
    From Newsgroup: comp.os.vms

    Craig A. Berry <craigberry@nospam.mac.com> wrote:

    On 9/8/25 9:05 PM, Waldek Hebisch wrote:
    Craig A. Berry <craigberry@nospam.mac.com> wrote:
    On 9/7/25 1:17 PM, Waldek Hebisch wrote:

    Yes, I st_ino on VMS is an array. I have now modified libgfortran
    to accomodate this.

    Yes and no. If you insist on using decades-old VAX C compatibility
    features, then st_ino is an array. Probably because you couldn't fit 3
    words into any integral type on VAX.

    If you define _USE_STD_STAT, though, then you get:

    typedef unsigned __int64 __ino_t;
    typedef __ino_t ino_t;

    You also get large file support, which you could get independently via
    _LARGEFILE if for some reason you had to. You definitely want
    _USE_STD_STAT for anything new and/or cross-platform. That gets you
    something that was POSIX-compliant a decade or two ago. It isn't
    compliant now because the file times are still just ints rather than
    structs with high-precision components as newer POSIX requires.

    Well, the contex is libgfortran, part of Fortran compiler. It is
    supposed to work with 60 years old Fortran code. Such code may need
    compatiblity features.

    I'm not sure I follow; that sounds like a conflation of compiler build
    time and compiler run time (user source build time) requirements.

    libgfortran is linked to user code. Quite possible that it
    can be compiled with different options than user code, but
    currently it uses default options which are right for legacy
    code.

    libgcc uses '--pointer-size=64' to build. I need to investigate
    which options are good for libgfortran, but it needs to be build
    in a way which is compatible with user code.
    --
    Waldek Hebisch
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Simon Clubley@clubley@remove_me.eisner.decus.org-Earth.UFP to comp.os.vms on Wed Sep 10 12:18:42 2025
    From Newsgroup: comp.os.vms

    On 2025-09-09, Waldek Hebisch <antispam@fricas.org> wrote:
    Simon Clubley <clubley@remove_me.eisner.decus.org-earth.ufp> wrote:
    On 2025-09-09, Craig A. Berry <craigberry@nospam.mac.com> wrote:
    Assuming you've copied the VMS headers over to Linux where you are
    building the compiler, the switch would just be -D_USE_STD_STAT.

    Copying the headers is what I did (with patches afterwards IIRC).
    Waldek OTOH said that he was creating his own headers. I don't know
    if that is still the case.

    I am using my own headers and my own (fake) libraries. Because
    may fakes are static libraries the resulting binary has no
    chance of working. I need to work out how to generate fake
    shared images, then binaries linked to fake libraries when
    transfed to VMS will use real libraries from the system and should
    work.


    I can see how you might be able to get this working with sharable
    images, but I am not seeing how you might get this working with
    .olb object module libraries, given that the contents are linked into
    the executable during linking and are not referenced at runtime.

    Unless there's something I am not seeing, that would mean the actual
    link would have to be done on VMS, and that you couldn't use binutils
    on Linux to create the actual VMS Alpha executable image.

    BTW, according to the messages I posted at the time, Waldek's C++
    build failure is identical to the one I experienced so clearly
    nothing has changed in this area since then.

    I have now fix or workaround for this issue, so build goes further.
    But I get different assembler error at later stage.


    Nice to see progress on C++. That means you have got further than
    I did with C++.

    Simon.
    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Wed Sep 10 13:29:42 2025
    From Newsgroup: comp.os.vms

    In article <109rl2h$r2qr$1@paganini.bofh.team>,
    Waldek Hebisch <antispam@fricas.org> wrote:
    Dan Cross <cross@spitfire.i.gajendra.net> wrote:
    In article <109o21i$g12m$1@paganini.bofh.team>,
    Waldek Hebisch <antispam@fricas.org> wrote:
    Craig A. Berry <craigberry@nospam.mac.com> wrote:
    On 9/7/25 1:17 PM, Waldek Hebisch wrote:
    [snip]
    Yes, I st_ino on VMS is an array. I have now modified libgfortran
    to accomodate this.

    Yes and no. If you insist on using decades-old VAX C compatibility
    features, then st_ino is an array. Probably because you couldn't fit 3 >>>> words into any integral type on VAX.

    If you define _USE_STD_STAT, though, then you get:

    typedef unsigned __int64 __ino_t;
    typedef __ino_t ino_t;

    You also get large file support, which you could get independently via >>>> _LARGEFILE if for some reason you had to. You definitely want
    _USE_STD_STAT for anything new and/or cross-platform. That gets you
    something that was POSIX-compliant a decade or two ago. It isn't
    compliant now because the file times are still just ints rather than
    structs with high-precision components as newer POSIX requires.

    Well, the contex is libgfortran, part of Fortran compiler. It is >>>supposed to work with 60 years old Fortran code. Such code may need >>>compatiblity features.

    This gets back to my original question: not all code in
    libgfortran is created the same. I doubt that 60-year old code
    cares about doing inode number+device equality to determine
    uniqueness of a file on a Unix system...particularly as Unix did
    not exist 60 years ago.

    Some code _may_ need that. My guess is that 99.99% wouldn't
    care and you can hack it for now to make forward progress.

    ATM I have single unconditional setup. I made progress,
    after changing 'st_ino' in header file be an array and
    small change to gfortran sources gfortran build works.

    ATM I did not look if/how gcc supports such switches. This is
    certainly thing to look at later, but now I want old stuff to
    work, when this works I can look at newer things.

    You'd just add `-D_USE_STD_STAT` as an additional compiler
    argument when building libgfortran, no?

    Unfortunately, within GCC build this is "hard way". Options
    are set by configure machinery and this is brittle and time
    consuming to test. Comparatively, changes to source files
    are easy.

    Odd. Usually the `autoconf` stuff gives you the option of
    adding extra flags for the C compiler with a switch to the
    `configure` script that it generates. Something like,

    `./configure --extra-cflags='-D_USE_STD_STAT' --whatever ...`

    It seems like that'd be a lot more robust. But as I said
    earlier, I'm not the one swinging the hammer here....

    - Dan C.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From antispam@antispam@fricas.org (Waldek Hebisch) to comp.os.vms on Wed Sep 10 14:13:36 2025
    From Newsgroup: comp.os.vms

    Simon Clubley <clubley@remove_me.eisner.decus.org-earth.ufp> wrote:
    On 2025-09-09, Waldek Hebisch <antispam@fricas.org> wrote:
    Simon Clubley <clubley@remove_me.eisner.decus.org-earth.ufp> wrote:
    On 2025-09-09, Craig A. Berry <craigberry@nospam.mac.com> wrote:
    Assuming you've copied the VMS headers over to Linux where you are
    building the compiler, the switch would just be -D_USE_STD_STAT.

    Copying the headers is what I did (with patches afterwards IIRC).
    Waldek OTOH said that he was creating his own headers. I don't know
    if that is still the case.

    I am using my own headers and my own (fake) libraries. Because
    may fakes are static libraries the resulting binary has no
    chance of working. I need to work out how to generate fake
    shared images, then binaries linked to fake libraries when
    transfed to VMS will use real libraries from the system and should
    work.


    I can see how you might be able to get this working with sharable
    images, but I am not seeing how you might get this working with
    .olb object module libraries, given that the contents are linked into
    the executable during linking and are not referenced at runtime.

    Unless there's something I am not seeing, that would mean the actual
    link would have to be done on VMS, and that you couldn't use binutils
    on Linux to create the actual VMS Alpha executable image.

    AFAICS everthing needed to run simple programs is provided by
    imagelib.olb. imagelib.olb is "shared image library", it does
    not contain code but only references to sharable images. I think
    that now I know enough to build "working" imagelib.olb. I put
    working in quote, because to really work is also needs sharable
    images which it references and that I need to work out.

    By default GNU ld also wants to use 'starlet.olb' and
    'sys$public_vectors'. I do not know if 'starlet.olb' is a "shared
    image library" or just static library. IIUC 'sys$public_vectors'
    is a sharable image. So at least programs that do not use
    'starlet.olb' should work after linking with fake shareable
    images. And I think that this includes a lot of code.

    People that need to link to static libraries will need to
    use real VMS libraries, that is clear.

    BTW, according to the messages I posted at the time, Waldek's C++
    build failure is identical to the one I experienced so clearly
    nothing has changed in this area since then.

    I have now fix or workaround for this issue, so build goes further.
    But I get different assembler error at later stage.


    Nice to see progress on C++. That means you have got further than
    I did with C++.

    Well, even geting reproducible failure is worthwhile. I reported
    failures in binutils to binutils developers and Alan Modra fixed
    them. So now binutils from developement trunk should work as
    well or better than the old ones.

    Part of this is finding guilty party. ATM I still do not know
    if assembler should make more effort to handle code generated
    by g++, or g++ should generate code more to the assembler
    liking.
    --
    Waldek Hebisch
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From hb0815@mw40171@mucweb.de to comp.os.vms on Wed Sep 10 21:03:34 2025
    From Newsgroup: comp.os.vms

    On 9/10/25 16:13, Waldek Hebisch wrote:

    By default GNU ld also wants to use 'starlet.olb' and
    'sys$public_vectors'. I do not know if 'starlet.olb' is a "shared
    image library" or just static library. IIUC 'sys$public_vectors'
    is a sharable image. So at least programs that do not use
    'starlet.olb' should work after linking with fake shareable
    images. And I think that this includes a lot of code.

    starlet.olb is an OBJECT library.

    You can fake the shareable image. You only need to have the very same
    symbol vector entries in the faked image as in the real one. That
    includes all the alias entries as well has spare and private entries.
    And you need to have the identical GSMATCH.

    If someone links /system you also need a SYS$BASE_IMAGE.EXE. A faked one should do, but I admit I never tried that.


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.os.vms on Wed Sep 10 23:55:40 2025
    From Newsgroup: comp.os.vms

    On Wed, 10 Sep 2025 10:48:51 -0000 (UTC), Waldek Hebisch wrote:

    Options are set by configure machinery and this is brittle and time
    consuming to test.

    Is this good old GNU Autotools? With the automatically-generated rCLconfigurerCY file that makes you lose your will to live trying to read it?

    Tip: donrCOt make changes to that. Make your changes to the m4 sources that are used to generate that file.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From antispam@antispam@fricas.org (Waldek Hebisch) to comp.os.vms on Tue Sep 16 19:24:56 2025
    From Newsgroup: comp.os.vms

    hb0815 <mw40171@mucweb.de> wrote:
    On 9/10/25 16:13, Waldek Hebisch wrote:

    By default GNU ld also wants to use 'starlet.olb' and
    'sys$public_vectors'. I do not know if 'starlet.olb' is a "shared
    image library" or just static library. IIUC 'sys$public_vectors'
    is a sharable image. So at least programs that do not use
    'starlet.olb' should work after linking with fake shareable
    images. And I think that this includes a lot of code.

    starlet.olb is an OBJECT library.

    You can fake the shareable image. You only need to have the very same
    symbol vector entries in the faked image as in the real one. That
    includes all the alias entries as well has spare and private entries.
    And you need to have the identical GSMATCH.

    If someone links /system you also need a SYS$BASE_IMAGE.EXE. A faked one should do, but I admit I never tried that.

    I have made a simple-minded generator of fake shared libraries.
    Using fake 'DECC$SHR.exe' containing just 5 real symbols (and
    hundreds of dummies to fill unused positions in symbol vector)
    I managed to link on Linux a simple "Hello from VMS" program
    and the program run correctly on VMS.

    I still have a problem: ATM I do not know how access to variables in
    shared images works. So I have bogus reference to 'C$_EXIT1'.

    I have noticed that VMS linker inserts reference to 'LIB$INITIALIZE',
    while with my fake libraries GNU linker does not reference this
    function.
    --
    Waldek Hebisch
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.os.vms on Tue Sep 16 20:41:53 2025
    From Newsgroup: comp.os.vms

    On Tue, 16 Sep 2025 19:24:56 -0000 (UTC), Waldek Hebisch wrote:

    I have noticed that VMS linker inserts reference to 'LIB$INITIALIZE',
    while with my fake libraries GNU linker does not reference this
    function.

    As I recall, a referenced library can have an initialization section. If present, this needs to run before the program mainline is entered. LIB$INITIALIZE is part of the mechanism for invoking all these
    initialization sections for all linked libraries, in some order (not sure
    if it can be controlled).

    The VMS .EXE file format allows for up to 3 transfer addresses. The
    program mainline entry point always comes last. LIB$INITIALIZE, if used,
    will be before that.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From hb0815@mw40171@mucweb.de to comp.os.vms on Wed Sep 17 23:40:04 2025
    From Newsgroup: comp.os.vms

    On 9/16/25 21:24, Waldek Hebisch wrote:

    I have made a simple-minded generator of fake shared libraries.
    Using fake 'DECC$SHR.exe' containing just 5 real symbols (and
    hundreds of dummies to fill unused positions in symbol vector)
    I managed to link on Linux a simple "Hello from VMS" program
    and the program run correctly on VMS.

    I still have a problem: ATM I do not know how access to variables in
    shared images works. So I have bogus reference to 'C$_EXIT1'.

    I don't see C$_EXIT1 in DECC$SHR on Alpha (Eisner, V8.4-2L2).

    C$_ are message codes, for example C$_ENOENT (%C-F-ENOENT, no such file
    or directory). That is integer literals.

    Read/write data symbols are as procedure symbols with EGSY$V_NORM clear. Literals symbols are as data with EGSY$V_REL clear.

    Create a small shareable image on VMS/Alpha with a procedure, data and
    an integer literal and you will see the flags and the differences in the values. With analyze/image or a full map you should be able to find the
    symbol vector in dump's output.

    I have noticed that VMS linker inserts reference to 'LIB$INITIALIZE',
    while with my fake libraries GNU linker does not reference this
    function.

    The linker does not insert such a reference. If the LIB$INITIALIZE
    module is included in the image, then it was explicitly included or
    there was a reference to a symbol defined in this module from one of the
    to be linked object modules.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From antispam@antispam@fricas.org (Waldek Hebisch) to comp.os.vms on Thu Sep 18 00:55:35 2025
    From Newsgroup: comp.os.vms

    hb0815 <mw40171@mucweb.de> wrote:
    On 9/16/25 21:24, Waldek Hebisch wrote:

    I have made a simple-minded generator of fake shared libraries.
    Using fake 'DECC$SHR.exe' containing just 5 real symbols (and
    hundreds of dummies to fill unused positions in symbol vector)
    I managed to link on Linux a simple "Hello from VMS" program
    and the program run correctly on VMS.

    I still have a problem: ATM I do not know how access to variables in
    shared images works. So I have bogus reference to 'C$_EXIT1'.

    I don't see C$_EXIT1 in DECC$SHR on Alpha (Eisner, V8.4-2L2).

    C$_ are message codes, for example C$_ENOENT (%C-F-ENOENT, no such file
    or directory). That is integer literals.

    Read/write data symbols are as procedure symbols with EGSY$V_NORM clear. Literals symbols are as data with EGSY$V_REL clear.

    Create a small shareable image on VMS/Alpha with a procedure, data and
    an integer literal and you will see the flags and the differences in the values. With analyze/image or a full map you should be able to find the symbol vector in dump's output.

    Thanks, GNU startup file declares C$_EXIT1 as:

    extern int C$_EXIT1;

    but later uses only address of it. I guess it is how one can access
    VMS literals from C. I am not sure why they are doing it this way,
    they just hardcode a buch of constants, but apparently want to
    reference symbol in this case.

    I worked out how to find symbol vector. GNU header files have
    definitions of various constants so I think I know how to set
    up entry for a constant.

    I have noticed that VMS linker inserts reference to 'LIB$INITIALIZE',
    while with my fake libraries GNU linker does not reference this
    function.

    The linker does not insert such a reference. If the LIB$INITIALIZE
    module is included in the image, then it was explicitly included or
    there was a reference to a symbol defined in this module from one of the
    to be linked object modules.

    Well, I tried:

    $ link CRT0.OBJ,CRTBEGIN.OBJ,HH.OBJ,crtend.obj,hh.opt/options /NOSYSLIB

    where hh.opt specifies linking with DECC$SHR.EXE and SYS$PUBLIC_VECTORS.EXE
    and linker complains about C$_EXIT1 and LIB$INITIALIZE being undefined.
    My object files have only 5 external references, 4 are resolved by DECC$SHR.EXE. C$_EXIT1 is referenced in CRT0.OBJ and defined by
    something in STARLET.OLB, but since I do not include STARLET.OLB in
    the link linker should complain. But there is no reference to
    LIB$INITIALIZE in the object files above. IIUC VMS shared libraries
    are "fully linked", that is normally shared library should not cause
    reference to some extra symbol. But LIB$INITIALIZE apparently is
    special. When I skip shared libraries from the link I get information
    about 5 unresolved symbols, so clearly referenct to LIB$INITIALIZE
    is triggered by linking shared libraries.

    BTW: I included SYS$PUBLIC_VECTORS.EXE in the link because after
    default linking executable references both DECC$SHR.EXE and SYS$PUBLIC_VECTORS.EXE. In particular executable uses slot
    number 282 in symbol vector of SYS$PUBLIC_VECTORS.EXE. This
    slot does not correspond to any function from official list
    of system services, so I suspected that this may be
    LIB$INITIALIZE. But apparently LIB$INITIALIZE is in STARLET.OLB
    and uses some unknown system service.

    BTW2: GNU linker has special logic which under same conditions
    (which I am trying to understand) will include LIB$INITIALIZE
    in the link.
    --
    Waldek Hebisch
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From hb0815@mw40171@mucweb.de to comp.os.vms on Thu Sep 18 15:58:00 2025
    From Newsgroup: comp.os.vms

    On 9/18/25 2:55 AM, Waldek Hebisch wrote:

    I have noticed that VMS linker inserts reference to 'LIB$INITIALIZE',
    while with my fake libraries GNU linker does not reference this
    function.

    The linker does not insert such a reference. If the LIB$INITIALIZE
    module is included in the image, then it was explicitly included or
    there was a reference to a symbol defined in this module from one of the
    to be linked object modules.

    Well, I tried:

    $ link CRT0.OBJ,CRTBEGIN.OBJ,HH.OBJ,crtend.obj,hh.opt/options /NOSYSLIB

    It gets hairy or confusing or both ...

    I assume the link was on VMS with object created with the binutils (on a non-VMS system). The 0 and BEGIN indicate that there is something that
    needs to be done at program start. (On my Linux system there is a
    crtbegin.o and that contains a section .init_array, the equivalent ELF
    section of the LIB$INITIALIZE PSECT.

    where hh.opt specifies linking with DECC$SHR.EXE and SYS$PUBLIC_VECTORS.EXE and linker complains about C$_EXIT1 and LIB$INITIALIZE being undefined.
    My object files have only 5 external references, 4 are resolved by DECC$SHR.EXE. C$_EXIT1 is referenced in CRT0.OBJ and defined by
    something in STARLET.OLB, but since I do not include STARLET.OLB in
    the link linker should complain. But there is no reference to
    LIB$INITIALIZE in the object files above. IIUC VMS shared libraries
    are "fully linked", that is normally shared library should not cause reference to some extra symbol. But LIB$INITIALIZE apparently is
    special. When I skip shared libraries from the link I get information
    about 5 unresolved symbols, so clearly referenct to LIB$INITIALIZE
    is triggered by linking shared libraries.

    LIB$INITIALIZE is a "normal" PSECT (and symbol and module name - just to confuse ...). The PSECT contains the addresses of the functions to be
    called at init time. Referencing the symbol is just a common hack/trick
    to trigger inclusion of the module. The (user) code should do noting at
    all with whatever the symbol references.

    If you link on VMS, create a full map with cross references and you will
    see what references LIB$INITIALIZE. The current binutils ld can also
    create map files with references.

    BTW: I included SYS$PUBLIC_VECTORS.EXE in the link because after
    default linking executable references both DECC$SHR.EXE and SYS$PUBLIC_VECTORS.EXE. In particular executable uses slot
    number 282 in symbol vector of SYS$PUBLIC_VECTORS.EXE. This
    slot does not correspond to any function from official list
    of system services, so I suspected that this may be
    LIB$INITIALIZE. But apparently LIB$INITIALIZE is in STARLET.OLB
    and uses some unknown system service.

    On Eisner, entry 282 in SYS$PUBLIC_VECTORS is SYS$NATIVE_TO_TRANSLATED.
    And yes, that's not an official system service.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From antispam@antispam@fricas.org (Waldek Hebisch) to comp.os.vms on Fri Sep 19 04:00:49 2025
    From Newsgroup: comp.os.vms

    hb0815 <mw40171@mucweb.de> wrote:
    On 9/18/25 2:55 AM, Waldek Hebisch wrote:

    I have noticed that VMS linker inserts reference to 'LIB$INITIALIZE',
    while with my fake libraries GNU linker does not reference this
    function.

    The linker does not insert such a reference. If the LIB$INITIALIZE
    module is included in the image, then it was explicitly included or
    there was a reference to a symbol defined in this module from one of the >>> to be linked object modules.

    Well, I tried:

    $ link CRT0.OBJ,CRTBEGIN.OBJ,HH.OBJ,crtend.obj,hh.opt/options /NOSYSLIB

    It gets hairy or confusing or both ...

    I assume the link was on VMS with object created with the binutils (on a non-VMS system). The 0 and BEGIN indicate that there is something that
    needs to be done at program start. (On my Linux system there is a
    crtbegin.o and that contains a section .init_array, the equivalent ELF section of the LIB$INITIALIZE PSECT.

    CRT0.OBJ, CRTBEGIN.OBJ and CRTEND.OBJ are "standard" gcc files.
    Sources are included in gcc tarball, but are a bit hairy due to
    multiple conditionals.

    Point is that using GNU linker those file just require 5 symbols:
    main, decc$main, decc$malloc, decc$atexit and C$_EXIT1. main is
    provided by HH.OBJ and in turn needs decc$puts. Using
    GHU linker on Linux and a fake library exportingh the 5 symbols
    above those files links fine and resulting executable runs on
    VMS. CRTBEGIN.OBJ and crtend.obj contain reference to
    LIB$INITIALIZE. But somewhat GNU linker treats it as "weak"
    reference and does not complain that LIB$INITIALIZE is absent.
    Apparently VMS linker insists on its presence.

    AFAIK CRTBEGIN.OBJ is responsible for program initialization, in
    particular for running things marked as 'constructors'. CRTEND.OBJ
    is resposible for finalization.

    where hh.opt specifies linking with DECC$SHR.EXE and SYS$PUBLIC_VECTORS.EXE >> and linker complains about C$_EXIT1 and LIB$INITIALIZE being undefined.
    My object files have only 5 external references, 4 are resolved by
    DECC$SHR.EXE. C$_EXIT1 is referenced in CRT0.OBJ and defined by
    something in STARLET.OLB, but since I do not include STARLET.OLB in
    the link linker should complain. But there is no reference to
    LIB$INITIALIZE in the object files above.

    Correction: there is a reference, but GNU linker does not mind
    when it is not present (while with normal symbols GNU linker complains
    loudly and refuses to create executable).

    IIUC VMS shared libraries
    are "fully linked", that is normally shared library should not cause
    reference to some extra symbol. But LIB$INITIALIZE apparently is
    special. When I skip shared libraries from the link I get information
    about 5 unresolved symbols, so clearly referenct to LIB$INITIALIZE
    is triggered by linking shared libraries.

    LIB$INITIALIZE is a "normal" PSECT (and symbol and module name - just to confuse ...). The PSECT contains the addresses of the functions to be
    called at init time. Referencing the symbol is just a common hack/trick
    to trigger inclusion of the module. The (user) code should do noting at
    all with whatever the symbol references.

    There is some magic which creates reference to LIB$INITIALIZE. Up to
    now I did not find code responsible for this reference, so I wronly
    thought that there are no reference.

    If you link on VMS, create a full map with cross references and you will
    see what references LIB$INITIALIZE. The current binutils ld can also
    create map files with references.

    BTW: I included SYS$PUBLIC_VECTORS.EXE in the link because after
    default linking executable references both DECC$SHR.EXE and
    SYS$PUBLIC_VECTORS.EXE. In particular executable uses slot
    number 282 in symbol vector of SYS$PUBLIC_VECTORS.EXE. This
    slot does not correspond to any function from official list
    of system services, so I suspected that this may be
    LIB$INITIALIZE. But apparently LIB$INITIALIZE is in STARLET.OLB
    and uses some unknown system service.

    On Eisner, entry 282 in SYS$PUBLIC_VECTORS is SYS$NATIVE_TO_TRANSLATED.
    And yes, that's not an official system service.

    Yes. When I skipped SYS$PUBLIC_VECTORS.EXE from the link VMS
    linker complained about missine SYS$IMGSTA, so for a moment
    I thought that slot number 282 corresponds to SYS$IMGSTA. But
    testing shows that SYS$IMGSTA corresponds to slot 52 and SYS$NATIVE_TO_TRANSLATED indeed corresponds to slot 282.

    Now I do not think that this reference to SYS$NATIVE_TO_TRANSLATED
    is important: it is probably only used when running translated VAX
    code which is presumably quite rare. OTOH calls to LIB$INITIALIZE
    seem to be important part of program startup and finalization,
    so I need to work out that.
    --
    Waldek Hebisch
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.os.vms on Fri Sep 19 04:50:44 2025
    From Newsgroup: comp.os.vms

    On Fri, 19 Sep 2025 04:00:49 -0000 (UTC), Waldek Hebisch wrote:

    When I skipped SYS$PUBLIC_VECTORS.EXE from the link VMS linker
    complained about missine SYS$IMGSTA, so for a moment I thought that
    slot number 282 corresponds to SYS$IMGSTA. But testing shows that
    SYS$IMGSTA corresponds to slot 52 and SYS$NATIVE_TO_TRANSLATED
    indeed corresponds to slot 282.

    SYS$IMGSTA is set as the program transfer address ahead of your actual
    program transfer address unless you do LINK/NODEBUG, as I recall.
    Without this option, the linker includes source line-number
    information, but not full debug symbol tables.

    If you do RUN/DEBUG, then SYS$IMGSTA detects this and starts up the
    debugger instead of your actual mainline. If /DEBUG is not specified
    on RUN, then it goes to your actual mainline.

    With LINK/DEBUG, I think you get full debugger symbols in your image,
    and a flag setting that tells SYS$IMGSTA to always go to the debugger
    (unless you do RUN/NODEBUG? I think that was it.)
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From hb0815@mw40171@mucweb.de to comp.os.vms on Fri Sep 19 16:43:35 2025
    From Newsgroup: comp.os.vms


    CRT0.OBJ, CRTBEGIN.OBJ and CRTEND.OBJ are "standard" gcc files.
    Sources are included in gcc tarball, but are a bit hairy due to
    multiple conditionals.

    Point is that using GNU linker those file just require 5 symbols:
    main, decc$main, decc$malloc, decc$atexit and C$_EXIT1. main is
    provided by HH.OBJ and in turn needs decc$puts. Using
    GHU linker on Linux and a fake library exportingh the 5 symbols
    above those files links fine and resulting executable runs on
    VMS. CRTBEGIN.OBJ and crtend.obj contain reference to
    LIB$INITIALIZE. But somewhat GNU linker treats it as "weak"
    reference and does not complain that LIB$INITIALIZE is absent.
    Apparently VMS linker insists on its presence.

    AFAIK CRTBEGIN.OBJ is responsible for program initialization, in
    particular for running things marked as 'constructors'. CRTEND.OBJ
    is resposible for finalization.

    A simplified view of the call flow: If there is an entry for init code
    in the image transfer array, then some code runs before the before the
    main program code runs. The entry points to code in the image. This code
    walks through the code entries in the init section and calls them. Once
    this code returns, the main entry of the program is called.

    The linker sets up the transfer array. On VMS the linker creates an
    entry for init code, when it sees/processes the LIB$INITIALIZE module.
    This module is (only) in STARLET.OLB.

    The LIB$INITIALIZE module brings in the code to walk the init section.

    By default, the C compiler on VMS does not set up any image init code.
    It seems that the GNU C compiler always requires and sets up image init
    code.

    Since all the magic is in the linkers and the fact that a simple program linked with the GNU linker works on VMS, it seems that the GNU linker
    has its own code to walk the init section. Only on VMS the GNU linker
    can have access to the LIB$INITIALIZE module from STARLET.OLB. So the
    code address in the init transfer entry seems to point to GNU generated
    code.

    It also seems that that the object module generated by GNU can be linked
    on VMS. For this to work the LIB$INITIALIZE module needs to be included.
    As said before, this is often done by referencing the symbol
    LIB$INITIALIZE. It seems on VMS, for GNU objects you always have to
    include the LIB$INITIALIZE module from STARLET.OLB. With the default
    /SYSLIB or by explicitly including the module.

    I don't know how the GNU linker resolves LIB$INITIALIZE. Without having
    access to the GNU object files I can only speculate. It's unlikely that
    one of the modules defines the symbol. This could create multiple
    defined symbols when linking on VMS and/or it could be that the VMS
    linker can not set up the init entry in the transfer array because the
    symbol is already resolved from a GNU object module. It's more likely
    that the GNU linker handles the LIB$INITIALIZE symbol specially.

    Again, I'm only guessing what the GNU linker does.

    The linker maps should help to understand what's going on.

    Also, on VMS there is no LIB$FINALIZE. So the GNU linker very likely
    sets up some init code to establish an exit handler to run finalization
    code.





    --- Synchronet 3.21a-Linux NewsLink 1.2