+ // Location to fix (in current chunk)
+ // We use the address of the chunk that loc is actually in, then
+ // subtract the chunk's starting location from loc to get the offset
+ // into the current chunk.
+ uint8_t * locp = cch->chptr + (loc - cch->chloc);
+
+ uint16_t eattr = 0; // Expression attrib
+ SYM * esym = NULL; // External symbol involved in expr
+ uint64_t eval; // Expression value
+ uint16_t flags; // Mark flags
+
+ // Compute expression/symbol value and attributes
+
+ // Complex expression
+ if (dw & FU_EXPR)
+ {
+ if (evexpr(fup->expr, &eval, &eattr, &esym) != OK)
+ continue;
+ }
+ // Simple symbol
+ else
+ {
+ SYM * sy = fup->symbol;
+ eattr = sy->sattr;
+
+ if (eattr & DEFINED)
+ eval = sy->svalue;
+ else
+ eval = 0;
+
+ // If the symbol is not defined, but global, set esym to sy
+ if ((eattr & (GLOBAL | DEFINED)) == GLOBAL)
+ esym = sy;
+ }
+
+ uint16_t tdb = eattr & TDB;
+
+ // If the expression/symbol is undefined and no external symbol is
+ // involved, then that's an error.
+ if (!(eattr & DEFINED) && (esym == NULL))
+ {
+ error(undef_error);
+ continue;
+ }
+
+ // Do the fixup
+ //
+ // If a PC-relative fixup is undefined, its value is *not* subtracted
+ // from the location (that will happen in the linker when the external
+ // reference is resolved).
+ //
+ // MWC expects PC-relative things to have the LOC subtracted from the
+ // value, if the value is external (that is, undefined at this point).
+ //
+ // PC-relative fixups must be DEFINED and either in the same section
+ // (whereupon the subtraction takes place) or ABS (with no subtract).
+ if (dw & FU_PCREL)