Summary
as370 does not reject operands whose relocation is not simply relocatable (net +1 in exactly one section). IFOX00 flags these IFO217 (RELOCATABILITY ERROR, severity 12) and zeroes the instruction; as370 silently emits wrong or garbage bytes. Found while analysing #21; not part of that fix (distinct root cause).
Cases (verified on as370 + real IFOX00, MVS 3.8j)
1. Multiply of a relocatable — L 1,FLDX*2-FLDX (value = FLDX)
IFOX00: IFO217, severity 12, instruction zeroed
as370 : 5810 0028 -- treats the whole expression as ABSOLUTE, base 0
as370's expr_val loses relocatability across the multiply, so it never reaches the USING path and emits an absolute base-0 reference.
2. Paren subterm spanning two sections — L 1,FLDX+(RELOC-FLDX) (RELOC in the CSECT, FLDX in a DSECT)
IFOX00: IFO217 (the paren subterm RELOC-FLDX is a cross-section difference)
as370 : FFF0 C008 -- garbage displacement
expr_sect skips parenthesised content wholesale (as370/src/as370.c expr_sect, the '(' branch), while expr_val evaluates it — the two disagree and produce a garbage displacement.
Minor, same area (note, don't split)
L 1,FLDX+(FLDY-FLDX) (a paren subterm that IS absolute — FLDY-FLDX cancels):
as370: 5814 C02C -- encodes a spurious INDEX register R4 (5814, not 5810)
The parenthesised subterm leaks into the RX index field — a paren-vs-subscript parsing quirk. The value resolves correctly (C02C), only the index nibble is wrong.
Root
as370 has no "simply relocatable" check on operand expressions: it should reject (IFO217) any operand whose net relocation isn't +1 in a single section, matching IFOX. The paren-skip in expr_sect and the multiply handling in expr_val are the two mechanisms that let non-simple expressions through.
Related: #21 (the analysis that surfaced these). #21's fix relies on "IFOX-accepted ⇒ expr_sect-correct", which holds precisely because these non-simple forms are IFOX-rejected — so this issue and #21 are complementary, not overlapping.
Summary
as370 does not reject operands whose relocation is not simply relocatable (net +1 in exactly one section). IFOX00 flags these IFO217 (RELOCATABILITY ERROR, severity 12) and zeroes the instruction; as370 silently emits wrong or garbage bytes. Found while analysing #21; not part of that fix (distinct root cause).
Cases (verified on as370 + real IFOX00, MVS 3.8j)
1. Multiply of a relocatable —
L 1,FLDX*2-FLDX(value = FLDX)as370's
expr_valloses relocatability across the multiply, so it never reaches the USING path and emits an absolute base-0 reference.2. Paren subterm spanning two sections —
L 1,FLDX+(RELOC-FLDX)(RELOC in the CSECT, FLDX in a DSECT)expr_sectskips parenthesised content wholesale (as370/src/as370.cexpr_sect, the'('branch), whileexpr_valevaluates it — the two disagree and produce a garbage displacement.Minor, same area (note, don't split)
L 1,FLDX+(FLDY-FLDX)(a paren subterm that IS absolute — FLDY-FLDX cancels):The parenthesised subterm leaks into the RX index field — a paren-vs-subscript parsing quirk. The value resolves correctly (C02C), only the index nibble is wrong.
Root
as370 has no "simply relocatable" check on operand expressions: it should reject (IFO217) any operand whose net relocation isn't +1 in a single section, matching IFOX. The paren-skip in
expr_sectand the multiply handling inexpr_valare the two mechanisms that let non-simple expressions through.Related: #21 (the analysis that surfaced these). #21's fix relies on "IFOX-accepted ⇒ expr_sect-correct", which holds precisely because these non-simple forms are IFOX-rejected — so this issue and #21 are complementary, not overlapping.