From d509ab7c4444ac34992409405accb83fa280f639 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 31 Oct 2017 12:26:54 +0000 Subject: [PATCH] ld: teach new tags, and make it reject them also tidy segment constraints --- Applications/MWC/cmd/asz80/ld.c | 37 ++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/Applications/MWC/cmd/asz80/ld.c b/Applications/MWC/cmd/asz80/ld.c index 35efc3cb..851a163d 100644 --- a/Applications/MWC/cmd/asz80/ld.c +++ b/Applications/MWC/cmd/asz80/ld.c @@ -147,6 +147,28 @@ static int is_undefined(const char *name) return 1; } +static void segment_mismatch(struct symbol *s, uint8_t type2) +{ + uint8_t seg1 = s->type & S_SEGMENT; + uint8_t seg2 = type2 & S_SEGMENT; + + /* Matching */ + if (seg1 == seg2) + return; + /* Existing entry was 'anything'. Co-erce to definition */ + if (seg1 == S_ANY) { + s->type &= ~S_SEGMENT; + s->type |= seg2; + return; + } + /* Regardless of the claimed type, an absolute definition fulfills + any need. */ + if (seg2 == ABSOLUTE) + return; + fprintf(stderr, "Segment mismatch for symbol '%.16s'.\n", s->name); + err |= 2; +} + static struct symbol *find_alloc_symbol(struct object *o, uint8_t type, const char *id, uint16_t value) { uint8_t hash = hash_symbol(id); @@ -165,18 +187,15 @@ static struct symbol *find_alloc_symbol(struct object *o, uint8_t type, const ch return s; } /* Already exists. See what is going on */ - if (type & S_UNKNOWN) + if (type & S_UNKNOWN) { /* We are an external reference to a symbol. No work needed */ + segment_mismatch(s, type); return s; + } if (s->type & S_UNKNOWN) { /* We are referencing a symbol that was previously unknown but which we define. Fill in the details */ - if ((s->type & S_SEGMENT) != S_ANY && - (s->type & S_SEGMENT) != (type & S_SEGMENT)) { - fprintf(stderr, "Segment mismatch for symbol '%s'.\n", id); - err |= 2; - } - s->type = type; + segment_mismatch(s, type); s->value = value; s->definedby = o; return s; @@ -423,6 +442,10 @@ static void relocate_stream(struct object *o, FILE * op, FILE * ip) fputc(REL_REL, op); continue; } + if (code == REL_LITTLEENDIAN) + continue; + if (code == REL_BIGENDIAN || code == REL_WORDMACHINE) + error("unsupported architecture"); /* Relocations */ size = ((code & S_SIZE) >> 4) + 1; -- 2.34.1