From c8e38145a549cdf7d1ca77ecc8fe0ca029ad1593 Mon Sep 17 00:00:00 2001 From: Andre Fachat Date: Sun, 15 Oct 2023 11:57:47 +0200 Subject: [PATCH] implement -L label defs and tests --- xa/misc/ldo65.c | 68 ++++++++++++++++++++++++++++++++++++-- xa/tests/ldoreloc/Makefile | 10 ++++-- 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/xa/misc/ldo65.c b/xa/misc/ldo65.c index cb20944..9521845 100644 --- a/xa/misc/ldo65.c +++ b/xa/misc/ldo65.c @@ -48,6 +48,9 @@ The process of linking works as follows: 2. Calculate new base addresses per segment 3. Merge all globals from all files into a single table, checking for duplicates 4. Resolve undefined labels, and merge remaining into global list +5. relocate all segments, create global relocation tables +6. verify undefined labels +7. write out target file */ @@ -105,6 +108,7 @@ file65 *load_file(char *fname); int read_options(unsigned char *f); int read_undef(unsigned char *f, file65 *fp); int write_undef(FILE *f, file65 *fp); +int check_undef(file65 *fp, char *defined[], int ndefined); int len_reloc_seg(unsigned char *buf, int ri); int reloc_seg(unsigned char *buf, int pos, int addr, int rdiff, int ri, unsigned char *obuf, int *lastaddrp, int *rop, file65 *fp); unsigned char *reloc_globals(unsigned char *, file65 *fp); @@ -149,6 +153,11 @@ int main(int argc, char *argv[]) { FILE *fd; int nundef = 0; // counter/index in list of remaining undef'd labels + char **defined = NULL; + char *arg; + int ndefined = 0; + int ndefalloc = 0; + if (argc <= 1) { usage(stderr); exit(1); @@ -178,6 +187,19 @@ int main(int argc, char *argv[]) { if(argv[i][2]) outfile=argv[i]+2; else outfile=argv[++i]; break; + case 'L': + if(argv[i][2]) arg=argv[i]+2; + else arg=argv[++i]; + if (ndefalloc == 0) { + ndefalloc = 20; + defined = malloc(ndefalloc * sizeof(char*)); + } else + if (ndefined >= ndefalloc) { + ndefalloc *= 2; + defined = realloc(defined, ndefalloc * sizeof(char*)); + } + defined[ndefined++] = arg; + break; case 'b': switch(argv[i][2]) { case 't': @@ -343,16 +365,28 @@ int main(int argc, char *argv[]) { dreloc[dro++] = 0; // ------------------------------------------------------------------------- - // step 7 - write out the resulting o65 file + // step 6 - validate undefined labels // - if (nundef > 0) { - if (!undefok) { + if (nundef > 0 && !undefok) { + int er = 0; + // we have undefined labels, but it's not ok (no -U) + // check -L defined labels + for(i=0;i>8) & 255; @@ -515,6 +549,34 @@ int write_undef(FILE *f, file65 *fp) { fprintf(f, "%s%c", current->name, 0); } } + return 0; +} + +int check_undef(file65 *fp, char *defined[], int ndefined) { + + int er = 0; + + for (int i = 0; i < fp->nundef; i++) { + undefs *current = &fp->ud[i]; + + if (current->resolved == -1) { + // only check unresolved entries + int found = 0; + for (int j = 0; j < ndefined; j++) { + if (defined && !strcmp(defined[j], current->name)) { + // label is found, so it's ok + found = 1; + break; + } + } + if (!found) { + fprintf(stderr, "Unresolved label '%s' from file '%s'\n", + current->name, fp->fname); + er = -1; + } + } + } + return er; } diff --git a/xa/tests/ldoreloc/Makefile b/xa/tests/ldoreloc/Makefile index 1a33638..2e46bdb 100644 --- a/xa/tests/ldoreloc/Makefile +++ b/xa/tests/ldoreloc/Makefile @@ -21,10 +21,13 @@ linked11.o65: 10.o65 2.o65 ../../ldo65 -U -o $@ 2.o65 10.o65 linked20.o65: 20.o65 2.o65 - ../../ldo65 -U -o $@ 2.o65 20.o65 + ../../ldo65 -Ll1 -o $@ 2.o65 20.o65 linked21.o65: 20.o65 2.o65 - ../../ldo65 -U -o $@ 20.o65 2.o65 + ../../ldo65 -L l1 -o $@ 20.o65 2.o65 + +linked22.o65: 20.o65 2.o65 + ../../ldo65 -o $@ 20.o65 2.o65 && exit 1 || exit 0 linked30.o65: 30.o65 31.o65 ../../ldo65 -o $@ 30.o65 31.o65 @@ -74,6 +77,9 @@ t21: linked21.o65 ../hextool $@ > $@.hex ../hextool -cmp=$@ < t21.ok +t22: linked22.o65 + # should fail, so no action + t30: linked30.o65 ../../reloc65 -bt 32768 -xt -o $@ $< ../hextool $@ > $@.hex