Skip to content

CC/370 v1.3.0

Choose a tag to compare

@github-actions github-actions released this 05 Oct 09:38
· 71 commits to main since this release
1c8181e

CC/370 (cc370) 1.3.0 is the host-native MVS 3.8j toolchain -- C compiler, assembler, linker and the transport tools -- with weak references in C, the last missing Assembler XF statements in as370 (COM, DXD, CXD, Q-type constants), and common sections linked the way IEWL links them. Most of the release fixes cases where a tool produced a wrong result without saying so. Source that compiled and linked with 1.2.0 still does. A few command-line behaviours changed, though, and every load module's first eight bytes differ (see below). It works with LIBC/370 (libc370) >= 2.1.0 (the .deb/.rpm say so; install.sh picks the newest LIBC/370 that accepts this CC/370).

Read this first: what a caller can see

  • -v is verbose and -V is the version, in every tool (#811). as370 -v and dasm370 -v used to print the version; they now print verbose output on stderr. Use --version or -V. Every tool, the cc370 driver included, takes -V/--version and -h/--help. cc370 --version is now the single line cc370 1.3.0 (<commit>), based on GCC 3.4.6.
  • as370 writes no object on a wrong command line (#822). An invalid option, a second source file or an unwritable -a=FILE ends with rc 16, as before, but no longer leaves an object behind. The assembly still runs and reports.
  • The eyecatcher in front of main names CC/370 (#813). It is DC C'CC370',AL1(1,3,0) where it was DC C'GCCMVS!!'. It has the same length and @@MAIN stays at offset 8, but every main module differs from a 1.2.0 build in those bytes, so a comparison against an older baseline shows them.
  • Trigraphs are on under every -std (#832). They used to be switched off by -std=gnu89/gnu99, so "x??!y" had two values. Write ?\?! for a literal ??!.
  • The cc370 driver (#808, #833):
    • An as370 warning (rc 4) no longer fails a compile.
    • -c/-S with several sources and one -o is refused.
    • -b/-V<version> are refused.
    • -pipe is accepted and ignored.
    • -mpickax is gone.
    • #pragma map/linkage warn that they have no effect.
  • ld370 return codes follow one rule (#821, #807): rc 2 when the command line is wrong whatever the files hold (nothing is written then), rc 1 when a file or the link fails. A few cases moved from rc 1 to rc 2: a name used twice in one library, more than 32 archives, and a --pack input that is not a load module.
  • ld370 --pack of a bare member takes the entry point from its CESD (#850): --entry NAME, else @@CRT0. Before, it packed at entry 0 and ignored --entry.
  • dasm370 without arguments, or given a file that is no deck or module, now ends rc 2 / rc 16 respectively (#809).

New

  • Weak references in C (#866): extern void f(void) __attribute__((weak)); becomes a WXTRN. Unresolved it is 0 (if (f) f();), and automatic library call does not pull a definer for it. There is no weak definition on MVS: one compiles as an ordinary definition and warns (-Wweak-definition; -Wno-weak-definition switches it off). __CC370_WEAK__ is predefined.
  • as370: COM, DXD, CXD and Q-type constants (#810, #229, #840), byte-identical to IFOX00, listings included.
  • ld370: common sections (#837): one area per name, as long as the longest contribution, after the objects -- IEWL's layout.
  • as370: IFO203 and IFO204, two of IFOX00's diagnostics for address and fixed-point constants that do not fit their field (#776, #840).

Fixed: before and now

before now
A(-SECT), A(-EXT), A(EXT-SECT) in as370 (#824) positive or no relocation -- wrong addresses at rc 0 one relocation per term, in its own direction
a common section in ld370 (#837) placed over the first section, outside the module length after the objects, longest wins
A(BLK), =A(BLK) on a COM name; =Q(PR) literal (#840) no relocation relocated as IFOX00 does
relocatable AL1/AL2/YL1 (#840) relocated with that length at rc 0 IFO204, value 0, as IFOX00
ld370 --pack of a bare member (#850) entry 0 the entry from its CESD
ar370 (#805) objects past 2048 dropped, names over 15 characters cut, at rc 0 no limits; long names in a GNU // table
ld370 inputs (#807) a non-deck file, an unknown option, a bad value accepted refused with rc 1 or 2
xmit370 (#804) member names cut to 8, values unchecked, a non-XMIT input not reported names refused or upper-cased, values checked, a non-XMIT input named
file370 (#806) source libraries read as load libraries, transmissions cut at 4 MB the library's RECFM decides; no size limit
floating-point constants in as370 (#761, #782, #783) modifiers and range limits wrong as IFOX00
a macro's LCLx in as370 (#786) overwrote a global of the same name a local of its own
cmplmd370 on a C module (#809) private code never paired, not even against itself paired by entry point
idrdump370 (#809) linkage-editor and translator records unreadable decoded

Install

The installer -- it installs CC/370 and the newest LIBC/370 that accepts it:

curl -fsSL https://github.com/mvslovers/cc370/releases/latest/download/install.sh | sh

With Homebrew (macOS, Linux):

brew trust mvslovers/tap            # once
brew install mvslovers/tap/cc370    # cc370 and, as its dependency, libc370
brew upgrade mvslovers/tap/cc370    # an existing install

Or the pieces, all listed in SHA256SUMS:

file what
cc370-1.3.0-{darwin,linux}-{amd64,arm64}.tar.gz the toolchain for one host
cc370_1.3.0_{amd64,arm64}.deb Debian/Ubuntu; depends on libc370-dev (>= 2.1.0)
cc370-1.3.0.{x86_64,aarch64}.rpm Fedora/RHEL; requires libc370-devel the same way
install.sh the installer above

Full changelog

Added

  • cc370: weak references (__attribute__((weak)) on a declaration).
    • A weak reference becomes a WXTRN (ESD type WX), written ahead of the
      first reference. Unresolved it is 0 (if (f) f();), and automatic
      library call does not pull a definer for it -- IEWL's rule, which ld370
      already followed.
    • An unreferenced weak declaration produces nothing.
    • MVS has no weak definition: one is compiled as an ordinary definition and
      warns with -Wweak-definition (on by default, so an -Werror build
      stops; -Wno-weak-definition switches it off).
    • __CC370_WEAK__ is predefined, so a library can test for the feature
      rather than for a version.
  • as370: COM, DXD, CXD and Q-type constants (#810, #229). They were
    the last Assembler XF statements and constant types it lacked: COM and
    DXD were undefined operation codes, CXD and DC Q(...) "not
    implemented".
    • COM opens a common section (ESD type CM): its own counter from zero, can
      be resumed, holds no text, and its symbols relocate against it.
    • DXD defines an external dummy section (XD) with the length and alignment
      of its operands.
    • CXD reserves a fullword that is not punched, with an RLD entry of type 3.
    • Q(name) gives an RLD entry of type 2 against the DXD or DSECT it names;
      a DSECT named this way becomes an XD. IFO231 is reported for a name not yet
      defined and IFO207 for one that is neither.
    • Decks and listings were measured on IFOX00 and are byte-identical up to the
      END card.
    • ld370 does not handle pseudo registers yet: they stay unresolved (#76).
      Common sections are allocated since #837.
  • as370: IFO203 (#776), severity 4, for a fixed-point or Y-type constant
    that does not fit its field: F'2147483648', H'65535', FL1'128',
    Y(32768). The signed range of the field decides, A-type is never flagged,
    and the bytes stay the low-order ones as before. Measured on IFOX00: as370
    flags the same 27 values in as370/tests/ifo203.s (FE9'3' since the
    exponent modifier, #782).

Changed

  • cc370: trigraphs under every -std (#832). They were on by default
    and off under -std=gnu89/gnu99, so "x??!y" was x|y in one build and
    x??!y in another. They are now always on (the library spells || as
    ??!??!); write ?\?! for a literal ??!.
  • cc370: -mpickax is gone (#834). It set a flag nothing read.
  • cc370: -pipe is accepted and ignored (#831). As370 reads a file, so
    -pipe failed rc 2 with no object; the output is the same without it.
  • cc370: #pragma map and #pragma linkage warn that they have no effect
    (#830). Both were dropped silently, so the external name stayed cc370's
    own; use __asm__("NAME").
  • -v is verbose and -V the version, in every tool (#811). Read this
    first:
    as370 -v and dasm370 -v used to print the version and now turn
    on verbose output. Use --version or -V instead.
    • as370 -v: the macro search path, each macro with the file it came from,
      and the summary line even on a clean assembly, all on stderr; the deck is
      unchanged.
    • dasm370 -v: the section read, with its origin, length, RLD and LD entries.
      dasm370 now asks as370 for its version with --version.
    • ar370: a trailing v (rcv) names each member written, as GNU ar does.
    • -V is new in as370, dasm370 and cmplmd370, and -h in as370 and dasm370,
      so every tool takes --version/-V and --help/-h.
    • The cc370 driver as well: -V prints the version and -h the usage. Its
      -v stays GCC's verbose mode. --version is now the one line
      cc370 <version> (<commit>), based on GCC 3.4.6, without GCC's copyright
      and warranty lines. GPLv2 asks for that announcement only from a program
      that reads commands interactively; the licence is in COPYING.
    • The driver refuses -b and -V<version> (#833). In GCC they start another
      installed driver: cc370 -bogus tried to run ogus-gcc-1.2.0.
  • The eyecatcher in front of main names CC/370 (#813). A program's
    main module carried DC C'GCCMVS!!', after the compiler CC/370 descends
    from; it is now DC C'CC370',AL1(major,minor,patch) -- in a dump
    C3C3F3F7F0 010201 for 1.2.1 -- so a module shows which CC/370 built it.
    Same 8 bytes, @@MAIN still at offset 8.

Fixed

  • as370 writes no object on a wrong command line (#822).
    • An invalid option or a second source file ended rc 16 and still wrote
      the object. The assembly still runs and reports, but no object is
      written.
    • -a=FILE that cannot be written fell back to stdout at rc 0. It is now
      rc 16 ("cannot write listing"), checked before the assembly.
    • Diagnostics name IFO177, IFO178, IFO224 and IFO236, where four
      of them said ERR -- IFOX00's internal label for the same number.
  • ld370 leftovers of #807 (#821).
    • --pack warns that --warn-shadow is ignored and refuses --include.
    • A --pack input that is not a load module (a C source, say) is rc 2,
      where it was warned about as a bare module and then failed rc 1.
    • Write errors carry the ld370: prefix.
    • An unwritable --map, .xmit or .iebcopy is reported before the member
      is written, so no member is left behind.
    • The return codes follow one rule: rc 2 when the command line is wrong
      whatever the files hold, rc 1 when a file or the link fails. A name used
      twice in a library (a member, or an alias naming the member or given
      twice) and more than 32 archives are therefore rc 2; a library or
      member not found, a file that is not an archive, and a member with a
      block larger than --blocksize stay rc 1.
  • idrdump370 decodes the linkage-editor and translator records (#809).
    • LKED: program, version, modification, date and time (5752SC104 V03 M08 date=26170 time=045427), where it printed stray characters.
    • Translator: each translator with its level, date and the sections it
      applies to.
    • --json lists an empty HMASPZAP record too, so idr and records agree.
    • --csect filters the HMASPZAP and IDENTIFY entries only; the
      linkage-editor and translator records are always shown.
    • A file that is not a load module is a format error, rc 2.
  • cmplmd370 pairs unnamed and empty sections (#809).
    • Private code (an unnamed section) paired only when a single one was left
      over, so a module linked from several C objects compared with ITSELF was
      "not in the reference" throughout. An unnamed section now pairs by its
      first entry point and is reported under it, as (ADDUP).
    • The entry-point pairing works both ways: a named section, such as the SD
      of cc370 -mcsect, also pairs with the unnamed section that owns the
      same entry.
    • An empty section is left out of the comparison.
    • A refusal (--csect naming no section, an incomplete image, nothing to
      compare) comes before
      anything is written to stdout; --json keeps its shape and --difout
      still carries every range.
    • The usage calls the operands NEW and REFERENCE, each an object deck or a
      load module.
  • cc370 -mcsect no longer opens an empty private-code section (#809).
    COPY PDPTOP's absolute EQUs ahead of the CSECT card opened one, as they do
    on IFOX00. The CSECT card now comes first and is resumed after the COPY. The
    text is unchanged.
  • ld370's bare-member warning prints the entry point in six hex digits
    (entry 000026), as file370 does.
  • dasm370 details (#809).
    • A file that is neither an object deck nor a load module is refused with
      rc 16 ("not an object deck or a load module"), where it used to be taken
      for an incomplete module, rc 2.
    • Called with no arguments, it prints the usage on stderr and ends rc 2, as
      cmplmd370 and idrdump370 do.
    • A common (CM) section is neither listed nor disassembled; --csect on one
      says it holds no text.
    • In a linked module, a section's first instruction was named after an entry
      point of another section that sits at module address 0 (@@CRT0). Labels
      now come from the section's own entries only.
    • The usage no longer lists --reach and --reach-OLD, which are refused;
      --reach-OLD is now an unknown option.
    • The usage and the messages carry no issue numbers or corpus statistics.
    • The man page gives the JSON schema as dasm370-repair/3.
  • ld370 --pack takes a bare member's entry point from its CESD (#850).
    A bare load module (one not linked with -iebcopy) was always packed with
    entry 0, and --entry was ignored. That held only while @@CRT0 came first
    in the module. Now --pack uses the address of --entry NAME, or of
    @@CRT0, in the member's own CESD. A name it does not find is refused with
    rc 1, and a module without @@CRT0 keeps entry 0, warned as before. A packed
    bare member is now identical to the direct -iebcopy link of the same module.
  • ld370 allocates common sections (#837). A CM section was placed at
    origin 0 of its object, on top of the object's first section, and was not
    counted in the module length, at rc 0. Now, as with IEWL, each common name
    becomes one area as long as its longest contribution. These areas follow
    every object on doubleword boundaries, carry no text, and count in the module
    length. Measured with IEWL on two objects sharing a common section of
    different lengths: CESD, control, text and RLD records are identical.
    --xref lists the address constants that point at a common section, as
    IEWL's cross-reference does (#845).
  • as370: COM and DXD names in address constants (#840).
    • A(BLK), A(BLK+4) and =A(BLK) on a COM section's own name got their
      value and no RLD entry at rc 0. They now relocate against the CM entry, as
      a field inside the section already did.
    • A =Q(PR) literal got no RLD entry; it now gets the same type-2 entry as
      DC Q(PR).
    • A DXD name in an A-con is a dummy-section term, as on IFOX00: A(PR) is
      IFO158.
    • The ESD page of the listing printed an ER that shares its name with a
      section under the section's id.
  • as370: IFO204 (#840). A relocatable A-type constant of 1 or 2 bytes, or a
    Y-type of 1, was assembled with an RLD entry of that length at rc 0. IFOX00
    rejects it: severity 8, value 0, no RLD entry.
  • The cc370 driver (#808):
    • An as370 warning (return code 4) no longer fails the command and deletes
      the object. 8 and above still do.
    • -c/-S with several sources and -o is refused. It used to run one
      cc1 over all of them and write one combined output.
    • --target-help prints cc1's target options with rc 0. It used to pass
      the option to as370 and ld370, which refused it, and then try a link.
    • -flinker-output= takes xmit or iebcopy and refuses anything else,
      on a link of objects alone as well.
    • -print-libgcc-file-name names libcc370rt.a.
    • --help sends bug reports to the CC/370 issue tracker.
    • A reference whose 8-character external name collides with another name
      of the same unit, defined or referenced, is warned like two definitions
      already were.
    • make test-driver runs these checks on an installed tree.
  • as370 relocates negative and mixed-sign address terms right (#824).
    A(-SECT), A(-EXT) and AL3(-EXT) got a positive RLD entry, and
    A(EXT-SECT), A(-SECT+EXT), A(SECT-EXT) none at all, so a module
    linked from them held wrong addresses with no diagnostic. A unary minus
    now counts, and an external reference is a relocation target of its own:
    one entry per term, in its own direction, as IFOX00 writes them.
  • xmit370 checks what it used to take or cut silently (#804). A derived
    member name longer than 8 characters was cut (verylongname.txt became
    VERYLONG); it is refused with the --member hint. --member names and
    --userid are upper-cased, and a userid over 8 characters is refused.
    --recfm f takes the record length as block size and refuses another;
    an impossible --stats-date is refused, not normalised; a non-numeric
    --tabs, --lrecl or --blocksize is refused. list/extract on a
    file that is not a transmission say so (rc 1 was silent). --latin1 on
    a UTF-8 file warns. An option given to a command it does not belong to is
    an error, --help/--version work anywhere, and INMR03's INMRECFM is
    named -- the same decoding as file370's, which now shows FB (not F) and
    INMR01's INMNUMF.
  • ld370 refuses what it used to take silently (#807). A file that is not
    an object deck linked at rc 0 into an empty member; it is refused with
    rc 1. An unknown option, or an option given last without its value, was
    taken as an input file; both are rc 2, and --help/-h and -V are new.
    A member name from --name or -o that is not a valid MVS name was
    accepted or cut (verylongname became VERYLONG); where it reaches a
    directory or the map it is refused. --ac above 255 (300 stored as 44)
    and a non-numeric --blocksize are refused. --pack names an XMIT, an
    archive or an object deck given as a member, refuses --name, and warns
    that --sparse-text/--allow-unresolved do not apply. A dropped duplicate
    CSECT is named in a note (rc unchanged, as IEWL's). The LKED IDR carries
    the toolchain's version, not V01 M00, and -v counts an LR as an LR.
  • file370 reads source libraries and large transmissions right (#806).
    The directory of a source library (as xmit370 create writes it) was
    decoded as a load library's, its ISPF statistics shown as entry point,
    length and attributes; COPYR1's RECFM now decides, and the heading names
    it. Data of a transmission past 4 MB was cut without a word; it is kept
    whole. --json over several files is one JSON array (one file still one
    object), names are escaped, an object deck carries its ESD as a load
    module carries its CESD, and any other file reports its format;
    --json implies --csects. INMR03's record format is named, - reads
    standard input, and a text file beginning with a space or @..O is no
    longer taken for a load module.
  • ar370 no longer drops or cuts anything silently (#805). More than 2048
    objects or 16384 symbols were dropped at rc 0; they have no limit now. A
    member name longer than 15 characters was cut to 16 bytes; it goes into a
    GNU // long-name member, which ld370 already reads, and a name longer
    than 63 characters is refused. Only object decks are stored -- a source
    file or an archive given as input is an error. The operation is matched
    whole (ar370 --version x created an empty archive x); --help/-h
    and -V are new. t lists member names without the trailing / and
    names the member behind every symbol. rc replaces an existing archive;
    the manual now says so.
  • as370: an open-code MNOTE substitutes its variable symbols (#799).
    MNOTE 1,'X=&X' printed X=&X; it is now listed as written, followed by
    the generated statement 1,X=ABC with its +, and the message is on that
    one -- as IFOX00 lists it. MNOTEs inside macros were never affected.
  • as370: floating-point range and modifier limits (#783). E'1E76' was
    silent with a wrapped characteristic; IFOX00 says IFO201 and writes 1.0,
    because a value exponent plus modifier outside -85..75 is taken as zero
    (ifnx5f). A characteristic outside 0..127 (E'7.3E75', E'1E-80') is
    IFO239 and the constant all zeros; a scale or exponent modifier outside
    DCTABLE's limits is IFO200 / IFO201 and taken as zero. All severity 8,
    measured on IFOX00 (as370/tests/dcfperr.s).
  • as370: the scale and exponent modifiers on E, D and L (#761). DS2'1.5'
    was written normalised (41180000…); it is 43001800…. The fraction is
    rounded at its normalised precision, shifted right S hex digits with the
    characteristic raised by S, and the shifted-out digits are dropped;
    IFO202 (severity 8) when no bit of the fraction is left, as ifnx5f tests
    it. En adds to the value's exponent. Measured on IFOX00
    (as370/tests/dcmod.s, as370/tests/dcscale.s).
  • as370: the exponent modifier on F and H (#782). FE9'2' assembled as
    2; it is 2E9. The value is mantissa x 10**(value exponent + modifier) x
    2**scale in exact arithmetic, rounded half away from zero, the exponent
    before the scale -- all measured on IFOX00 (as370/tests/dcmod.s). A value
    exponent alone (F'1E2') is honoured too, on the DC and the literal path.
    FE9'3' now gets the IFO203 that #780 had left open.
  • as370: a macro's LCLx no longer overwrites a global (#786). A name
    declared GBLx anywhere was global in every context, so a macro's LCLA &M
    wrote and reset the open code's global &M. IFNX5M lost 384 bytes of its
    opcode table at rc 8; it is now identical to IFOX00, and nothing else in
    the 5,528-module tree moved.
  • A fullword constant is emitted signed (#776). The words of a floating
    constant reached the backend unsigned on a 64-bit host, so the low word of
    1e32 came out as DC F'3558193243', which IFOX00 flags IFO203 (rc 4).
    Now DC F'-736774053': the same bits, so the deck does not change. Of
    LIBC/370's 724 C sources only strtod.c was affected.