+ // We do it this way because we have continues everywhere... :-P
+ FIXUP * fup = fixup;
+ fixup = fixup->next;
+
+ uint32_t dw = fup->attr; // Fixup long (type + modes + flags)
+ uint32_t loc = fup->loc; // Location to fixup
+ cfileno = fup->fileno;
+ curlineno = fup->lineno;
+ DEBUG { printf("ResolveFixups: sect#=%u, l#=%u, attr=$%X, loc=$%X, expr=%p, sym=%p, org=$%X\n", sno, fup->lineno, fup->attr, fup->loc, (void *)fup->expr, (void *)fup->symbol, fup->orgaddr); }
+
+ // This is based on global vars cfileno, curfname :-P
+ // This approach is kinda meh as well. I think we can do better
+ // than this.
+ SetFilenameForErrorReporting();
+
+ if ((sno == M56001P) || (sno == M56001X) || (sno == M56001Y) || (sno == M56001L))
+ loc = fup->orgaddr;
+
+ // Search for chunk containing location to fix up; compute a
+ // pointer to the location (in the chunk). Often we will find the
+ // Fixup is in the "cached" chunk, so the linear-search is seldom
+ // executed.
+ if (loc < cch->chloc || loc >= (cch->chloc + cch->ch_size))
+ {
+ for(cch=sc->sfcode; cch!=NULL; cch=cch->chnext)
+ {
+ if (loc >= cch->chloc && loc < (cch->chloc + cch->ch_size))
+ break;
+ }
+
+ if (cch == NULL)
+ {
+ // Fixup (loc) is out of range--this should never happen!
+ // Once we call this function, it winds down immediately; it
+ // doesn't return.
+ interror(7);
+ }
+ }
+
+ // 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)
+ {
+ // evexpr presumably issues the errors/warnings here
+ if (evexpr(fup->expr, &eval, &eattr, &esym) != OK)
+ continue;
+
+ if ((CHECK_OPTS(OPT_PC_RELATIVE)) && (eattr & REFERENCED) && (eattr & DEFINED) && (!(eattr & EQUATED)))
+ {
+ error("relocation not allowed");
+ continue;
+ }
+ }
+ // Simple symbol
+ else
+ {
+ SYM * sy = fup->symbol;
+ eattr = sy->sattr;
+
+ if ((CHECK_OPTS(OPT_PC_RELATIVE)) && (eattr & REFERENCED) && (eattr & DEFINED) && (!(eattr & EQUATED)))
+ {
+ error("relocation not allowed");
+ continue;
+ }
+
+ if (eattr & DEFINED)
+ eval = sy->svalue;
+ else
+ eval = 0;