1 /* xa65 - 65xx/65816 cross-assembler and utility suite
2  *
3  * Copyright (C) 1989-1997 Andr� Fachat (a.fachat@physik.tu-chemnitz.de)
4  *
5  * Label management module (also see xau.c)
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21 
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <ctype.h>
26 
27 /* structs and defs */
28 
29 #include "xad.h"
30 #include "xah.h"
31 #include "xar.h"
32 #include "xah2.h"
33 #include "xap.h"
34 #include "xa.h"
35 
36 /* externals */
37 
38 #include "xam.h"
39 #include "xal.h"
40 
41 /* exported globals */
42 
43 char   *lz;
44 
45 /* local prototypes */
46 
47 static int b_fget(int*,int);
48 static int b_ltest(int,int);
49 static int b_get(int*);
50 static int b_test(int);
51 static int ll_def(char *s, int *n, int b);
52 
53 /* local variables */
54 
55 /*
56 static int hashindex[256];
57 static Labtab *lt = NULL;
58 static int    lti = 0;
59 static int    ltm = 0;
60 */
61 
62 /*
63 static char   *ln;
64 static unsigned long lni;
65 static long   sl;
66 */
67 
68 static Labtab *ltp;
69 
l_init(void)70 int l_init(void)
71 {
72 	return 0;
73 #if 0
74      int er;
75 
76      for(er=0;er<256;er++)
77           hashindex[er]=0;
78 
79      /*sl=(long)sizeof(Labtab);*/
80 
81 /*     if(!(er=m_alloc((long)(sizeof(Labtab)*ANZLAB),(char**)&lt)))
82           er=m_alloc((long)LABMEM,&ln);*/
83 
84      er=m_alloc((long)(sizeof(Labtab)*ANZLAB),(char**)&lt);
85 
86      lti=0;
87 /*     lni=0L;*/
88 
89      return(er);
90 #endif
91 }
92 
ga_lab(void)93 int ga_lab(void)
94 {
95 	return(afile->la.lti);
96 }
97 
gm_lab(void)98 int gm_lab(void)
99 {
100 	return(ANZLAB);
101 }
102 
gm_labm(void)103 long gm_labm(void)
104 {
105 	return((long)LABMEM);
106 }
107 
ga_labm(void)108 long ga_labm(void)
109 {
110 	return(0 /*lni*/);
111 }
112 
printllist(fp)113 void printllist(fp)
114 FILE *fp;
115 {
116      int i;
117      LabOcc *p;
118      char *fname = NULL;
119 
120      for(i=0;i<afile->la.lti;i++)
121      {
122          ltp=afile->la.lt+i;
123          fprintf(fp,"%s, 0x%04x, %d, 0x%04x\n",ltp->n,ltp->val,ltp->blk,
124 							ltp->afl);
125 	 p = ltp->occlist;
126 	 if(p) {
127 	   while(p) {
128 	     if(fname != p->fname) {
129 		if(p!=ltp->occlist) fprintf(fp,"\n");
130 		fprintf(fp,"    %s",p->fname);
131 		fname=p->fname;
132 	     }
133 	     fprintf(fp," %d", p->line);
134 	     p=p->next;
135 	   }
136 	   fprintf(fp,"\n");
137 	 }
138 	 fname=NULL;
139      }
140 }
141 
lg_set(char * s)142 int lg_set(char *s ) {
143 	int n, er;
144 
145 	er = ll_search(s,&n);
146 
147 	if(er==E_OK) {
148 	  fprintf(stderr,"Warning: global label doubly defined!\n");
149 	} else {
150           if(!(er=ll_def(s,&n,0))) {
151             ltp=afile->la.lt+n;
152             ltp->fl=2;
153             ltp->afl=SEG_UNDEF;
154           }
155       	}
156 	return er;
157 }
158 
159 
l_def(char * s,int * l,int * x,int * f)160 int l_def(char *s, int *l, int *x, int *f)
161 {
162      int n,er,b,i=0;
163 
164      *f=0;
165      b=0;
166      n=0;
167 
168      if(s[0]=='-')
169      {
170           *f+=1;
171           i++;
172      } else
173      if(s[0]=='+')
174      {
175           i++;
176           n++;
177           b=0;
178      }
179      while(s[i]=='&')
180      {
181           n=0;
182           i++;
183           b++;
184      }
185      if(!n)
186           b_fget(&b,b);
187 
188 
189      if(!isalpha(s[i]) && s[i]!='_')
190           er=E_SYNTAX;
191      else
192      {
193           er=ll_search(s+i,&n);
194 
195           if(er==E_OK)
196           {
197                ltp=afile->la.lt+n;
198 
199                if(*f)
200                {
201                     *l=ltp->len+i;
202                } else
203                if(ltp->fl==0)
204                {
205                     *l=ltp->len+i;
206                     if(b_ltest(ltp->blk,b))
207                          er=E_LABDEF;
208                     else
209                          ltp->blk=b;
210 
211                } else
212                     er=E_LABDEF;
213           } else
214           if(er==E_NODEF)
215           {
216                if(!(er=ll_def(s+i,&n,b))) /* ll_def(...,*f) */
217                {
218                     ltp=afile->la.lt+n;
219                     *l=ltp->len+i;
220                     ltp->fl=0;
221                }
222           }
223 
224           *x=n;
225      }
226      return(er);
227 }
228 
l_search(char * s,int * l,int * x,int * v,int * afl)229 int l_search(char *s, int *l, int *x, int *v, int *afl)
230 {
231      int n,er,b;
232 
233      *afl=0;
234 
235      er=ll_search(s,&n);
236 /*printf("l_search: lab=%s(l=%d), afl=%d, er=%d, n=%d\n",s,*l, *afl,er,n);*/
237      if(er==E_OK)
238      {
239           ltp=afile->la.lt+n;
240           *l=ltp->len;
241           if(ltp->fl == 1)
242           {
243                l_get(n,v,afl);/*               *v=lt[n].val;*/
244                *x=n;
245           } else
246           {
247                er=E_NODEF;
248                lz=ltp->n;
249                *x=n;
250           }
251      }
252      else
253      {
254           b_get(&b);
255           er=ll_def(s,x,b); /* ll_def(...,*v); */
256 
257           ltp=afile->la.lt+(*x);
258 
259           *l=ltp->len;
260 
261           if(!er)
262           {
263                er=E_NODEF;
264                lz=ltp->n;
265           }
266      }
267      return(er);
268 }
269 
l_vget(int n,int * v,char ** s)270 int l_vget(int n, int *v, char **s)
271 {
272      ltp=afile->la.lt+n;
273      (*v)=ltp->val;
274      *s=ltp->n;
275      return 0;
276 }
277 
l_addocc(int n,int * v,int * afl)278 void l_addocc(int n, int *v, int *afl) {
279      LabOcc *p, *pp;
280 
281      (void)v;		/* quench warning */
282      (void)afl;		/* quench warning */
283      ltp = afile->la.lt+n;
284      pp=NULL;
285      p = ltp->occlist;
286      while(p) {
287 	if (p->line == filep->fline && p->fname == filep->fname) return;
288 	pp = p;
289 	p = p->next;
290      }
291      p = malloc(sizeof(LabOcc));
292      if(!p) {
293 	fprintf(stderr,"Oops, out of memory!\n");
294 	exit(1);
295      }
296      p->next = NULL;
297      p->line = filep->fline;
298      p->fname = filep->fname;
299      if(pp) {
300        pp->next = p;
301      } else {
302        ltp->occlist = p;
303      }
304 }
305 
l_get(int n,int * v,int * afl)306 int l_get(int n, int *v, int *afl)
307 {
308      if(crossref) l_addocc(n,v,afl);
309 
310      ltp=afile->la.lt+n;
311      (*v)=ltp->val;
312      lz=ltp->n;
313      *afl = ltp->afl;
314 /*printf("l_get('%s'(%d), v=$%04x, afl=%d, fl=%d\n",ltp->n, n, *v, *afl, ltp->fl);*/
315      return( (ltp->fl==1) ? E_OK : E_NODEF);
316 }
317 
l_set(int n,int v,int afl)318 void l_set(int n, int v, int afl)
319 {
320      ltp=afile->la.lt+n;
321      ltp->val = v;
322      ltp->fl = 1;
323      ltp->afl = afl;
324 /*printf("l_set('%s'(%d), v=$%04x, afl=%d\n",ltp->n, n, v, afl);*/
325 }
326 
ll_exblk(int a,int b)327 static void ll_exblk(int a, int b)
328 {
329      int i;
330      for (i=0;i<afile->la.lti;i++)
331      {
332           ltp=afile->la.lt+i;
333           if((!ltp->fl) && (ltp->blk==a))
334                ltp->blk=b;
335      }
336 }
337 
ll_def(char * s,int * n,int b)338 static int ll_def(char *s, int *n, int b)          /* definiert naechstes Label  nr->n     */
339 {
340      int j=0,er=E_NOMEM,hash;
341      char *s2;
342 
343 /*printf("ll_def: s=%s\n",s);    */
344 
345      if(!afile->la.lt) {
346 	afile->la.lti = 0;
347 	afile->la.ltm = 1000;
348 	afile->la.lt = malloc(afile->la.ltm * sizeof(Labtab));
349      }
350      if(afile->la.lti>=afile->la.ltm) {
351 	afile->la.ltm *= 1.5;
352 	afile->la.lt = realloc(afile->la.lt, afile->la.ltm * sizeof(Labtab));
353      }
354      if(!afile->la.lt) {
355 	fprintf(stderr, "Oops: no memory!\n");
356 	exit(1);
357      }
358 #if 0
359      if((lti<ANZLAB) /*&&(lni<(long)(LABMEM-MAXLAB))*/)
360      {
361 #endif
362           ltp=afile->la.lt+afile->la.lti;
363 /*
364           s2=ltp->n=ln+lni;
365 
366           while((j<MAXLAB-1) && (s[j]!='\0') && (isalnum(s[j]) || s[j]=='_'))
367           {
368                s2[j]=s[j];
369                j++;
370           }
371 */
372 	  while((s[j]!='\0') && (isalnum(s[j]) || (s[j]=='_'))) j++;
373 	  s2 = malloc(j+1);
374 	  if(!s2) {
375 		fprintf(stderr,"Oops: no memory!\n");
376 		exit(1);
377 	  }
378 	  strncpy(s2,s,j);
379 	  s2[j]=0;
380 /*
381           if(j<MAXLAB)
382           {
383 */
384                er=E_OK;
385                ltp->len=j;
386 	       ltp->n = s2;
387                ltp->blk=b;
388                ltp->fl=0;
389                ltp->afl=0;
390                ltp->occlist=NULL;
391                hash=hashcode(s,j);
392                ltp->nextindex=afile->la.hashindex[hash];
393                afile->la.hashindex[hash]=afile->la.lti;
394                *n=afile->la.lti;
395                afile->la.lti++;
396 /*               lni+=j+1;*/
397 /*          }
398      }
399 */
400 /*printf("ll_def return: %d\n",er);*/
401      return(er);
402 }
403 
404 
405 int ll_search(char *s, int *n)          /* search Label in Tabelle ,nr->n    */
406 {
407      int i,j=0,k,er=E_NODEF,hash;
408 
409      while(s[j] && (isalnum(s[j])||(s[j]=='_')))  j++;
410 
411      hash=hashcode(s,j);
412      i=afile->la.hashindex[hash];
413 
414 /*printf("search?\n");*/
415      if(i>=afile->la.ltm) return E_NODEF;
416 
417      do
418      {
419           ltp=afile->la.lt+i;
420 
421           if(j==ltp->len)
422           {
423                for (k=0;(k<j)&&(ltp->n[k]==s[k]);k++);
424 
425                if((j==k)&&(!b_test(ltp->blk)))
426                {
427                     er=E_OK;
428                     break;
429                }
430           }
431 
432           if(!i)
433                break;
434 
435           i=ltp->nextindex;
436 
437      }while(1);
438 
439      *n=i;
440 #if 0
441      if(er!=E_OK && er!=E_NODEF)
442      {
443           fprintf(stderr, "Fehler in ll_search:er=%d\n",er);
444           getchar();
445      }
446 #endif
447      return(er);
448 }
449 
450 int ll_pdef(char *t)
451 {
452 	int n;
453 
454 	if(ll_search(t,&n)==E_OK)
455 	{
456 		ltp=afile->la.lt+n;
457 		if(ltp->fl)
458 			return(E_OK);
459 	}
460 	return(E_NODEF);
461 }
462 
463 int l_write(FILE *fp)
464 {
465      int i, afl, n=0;
466 
467      if(noglob) {
468 	fputc(0, fp);
469 	fputc(0, fp);
470 	return 0;
471      }
472      for (i=0;i<afile->la.lti;i++) {
473         ltp=afile->la.lt+i;
474 	if((!ltp->blk) && (ltp->fl==1)) {
475 	  n++;
476 	}
477      }
478      fputc(n&255, fp);
479      fputc((n>>8)&255, fp);
480      for (i=0;i<afile->la.lti;i++)
481      {
482           ltp=afile->la.lt+i;
483           if((!ltp->blk) && (ltp->fl==1)) {
484 	    fprintf(fp, "%s",ltp->n);
485 	    fputc(0,fp);
486 	    afl = ltp->afl;
487             /* hack to switch undef and abs flag from internal to file format */
488 /*printf("label %s, afl=%04x, A_FMASK>>8=%04x\n", ltp->n, afl, A_FMASK>>8);*/
489             if( (afl & (A_FMASK>>8)) < SEG_TEXT) afl^=1;
490 	    fputc(afl,fp);
491 	    fputc(ltp->val&255, fp);
492 	    fputc((ltp->val>>8)&255, fp);
493 	  }
494      }
495      /*fputc(0,fp);*/
496      return 0;
497 }
498 
499 static int bt[MAXBLK];
500 static int blk;
501 static int bi;
502 
503 int b_init(void)
504 {
505      blk =0;
506      bi =0;
507      bt[bi]=blk;
508 
509      return(E_OK);
510 }
511 
512 int b_depth(void)
513 {
514      return bi;
515 }
516 
517 int ga_blk(void)
518 {
519 	return(blk);
520 }
521 
522 int b_open(void)
523 {
524      int er=E_BLKOVR;
525 
526      if(bi<MAXBLK-1)
527      {
528           bt[++bi]=++blk;
529 
530           er=E_OK;
531      }
532      return(er);
533 }
534 
535 int b_close(void)
536 {
537 
538      if(bi)
539      {
540           ll_exblk(bt[bi],bt[bi-1]);
541           bi--;
542      } else {
543 	  return E_BLOCK;
544      }
545 
546      return(E_OK);
547 }
548 
549 static int b_get(int *n)
550 {
551      *n=bt[bi];
552 
553      return(E_OK);
554 }
555 
556 static int b_fget(int *n, int i)
557 {
558      if((bi-i)>=0)
559           *n=bt[bi-i];
560      else
561           *n=0;
562      return(E_OK);
563 }
564 
565 static int b_test(int n)
566 {
567      int i=bi;
568 
569      while( i>=0 && n!=bt[i] )
570           i--;
571 
572      return( i+1 ? E_OK : E_NOBLK );
573 }
574 
575 static int b_ltest(int a, int b)    /* testet ob bt^-1(b) in intervall [0,bt^-1(a)]   */
576 {
577      int i=0,er=E_OK;
578 
579      if(a!=b)
580      {
581           er=E_OK;
582 
583           while(i<=bi && b!=bt[i])
584           {
585                if(bt[i]==a)
586                {
587                     er=E_NOBLK;
588                     break;
589                }
590                i++;
591           }
592      }
593      return(er);
594 }
595 
596