as: fix handling of unknown symbols in subtraction
authorAlan Cox <alan@linux.intel.com>
Sun, 29 Oct 2017 16:34:19 +0000 (16:34 +0000)
committerAlan Cox <alan@linux.intel.com>
Sun, 29 Oct 2017 16:34:19 +0000 (16:34 +0000)
Propogate segment requirements to object module for linker to fault

Applications/MWC/cmd/asz80/as3.c
Applications/MWC/cmd/asz80/as4.c

index cedc59a..8125e05 100644 (file)
@@ -89,10 +89,23 @@ static void chksegment(ADDR *left, ADDR *right, int op)
                return;
        }
        /* Subtraction within segment produces an absolute */
-       if (left->a_segment == right->a_segment && op == '-') {
-               left->a_segment = ABSOLUTE;
-               left->a_sym = NULL;
-               return;
+       if (op == '-') {
+               /* Unknown symbols may get segment forced as a result */
+               if (left->a_segment == -1) {
+                       left->a_segment = right->a_segment;
+                       if (left->a_sym)
+                               left->a_sym->s_segment = left->a_segment;
+               }
+               if (right->a_segment == -1) {
+                       right->a_segment = left->a_segment;
+                       if (right->a_sym)
+                               right->a_sym->s_segment = right->a_segment;
+               }
+               if (left->a_segment == right->a_segment && op == '-') {
+                       left->a_segment = ABSOLUTE;
+                       left->a_sym = NULL;
+                       return;
+               }
        }
        left->a_sym = NULL;
        aerr(MUST_BE_ABSOLUTE);
@@ -204,7 +217,7 @@ void expr2(ADDR *ap)
                expr3(ap, c);
                return;
        }
-       if (isalpha(c)) {
+       if (isalpha(c) || c == '_') {
                getid(id, c);
                if ((sp=lookup(id, uhash, 0)) == NULL
                &&  (sp=lookup(id, phash, 0)) == NULL)
index de60662..5e528c2 100644 (file)
@@ -137,8 +137,9 @@ static void putsymbol(SYM *s, FILE *ofp)
        else {
                if (s->s_type & TPUBLIC)
                        flag |= S_PUBLIC;
-               flag |= s->s_segment;
        }
+       /* 0 absolute, 1-n segments, -1 don't care */
+       flag |= (s->s_segment & S_SEGMENT);
        putc(flag, ofp);
        fwrite(s->s_id, 16, 1, ofp);
        putc(s->s_value, ofp);