implement -L label defs and tests

This commit is contained in:
Andre Fachat 2023-10-15 11:57:47 +02:00
parent 633c36ee81
commit c8e38145a5
2 changed files with 73 additions and 5 deletions

View File

@ -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<j;i++) {
if (check_undef(fp[i], defined, ndefined)) {
er = -1;
}
}
if (er) {
fprintf(stderr, "%d Undefined labels remain - aborting\n", nundef);
exit(1);
}
}
// -------------------------------------------------------------------------
// step 7 - write out the resulting o65 file
//
// prepare header
hdr[ 6] = 0; hdr[ 7] = 0;
hdr[ 8] = tbase & 255; hdr[ 9] = (tbase>>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;
}

View File

@ -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