xref: /plan9-contrib/sys/src/cmd/ld/mod.c (revision 40d015479ed36701ae6dcfd8814f849fc6285e8d)
1*40d01547SDavid du Colombier #include	"l.h"
2*40d01547SDavid du Colombier 
3*40d01547SDavid du Colombier void
readundefs(char * f,int t)4*40d01547SDavid du Colombier readundefs(char *f, int t)
5*40d01547SDavid du Colombier {
6*40d01547SDavid du Colombier 	int i, n;
7*40d01547SDavid du Colombier 	Sym *s;
8*40d01547SDavid du Colombier 	Biobuf *b;
9*40d01547SDavid du Colombier 	char *l, buf[256], *fields[64];
10*40d01547SDavid du Colombier 
11*40d01547SDavid du Colombier 	if(f == nil)
12*40d01547SDavid du Colombier 		return;
13*40d01547SDavid du Colombier 	b = Bopen(f, OREAD);
14*40d01547SDavid du Colombier 	if(b == nil){
15*40d01547SDavid du Colombier 		diag("could not open %s: %r", f);
16*40d01547SDavid du Colombier 		errorexit();
17*40d01547SDavid du Colombier 	}
18*40d01547SDavid du Colombier 	while((l = Brdline(b, '\n')) != nil){
19*40d01547SDavid du Colombier 		n = Blinelen(b);
20*40d01547SDavid du Colombier 		if(n >= sizeof(buf)){
21*40d01547SDavid du Colombier 			diag("%s: line too long", f);
22*40d01547SDavid du Colombier 			errorexit();
23*40d01547SDavid du Colombier 		}
24*40d01547SDavid du Colombier 		memmove(buf, l, n);
25*40d01547SDavid du Colombier 		buf[n-1] = '\0';
26*40d01547SDavid du Colombier 		n = getfields(buf, fields, nelem(fields), 1, " \t\r\n");
27*40d01547SDavid du Colombier 		if(n == nelem(fields)){
28*40d01547SDavid du Colombier 			diag("%s: bad format", f);
29*40d01547SDavid du Colombier 			errorexit();
30*40d01547SDavid du Colombier 		}
31*40d01547SDavid du Colombier 		for(i = 0; i < n; i++){
32*40d01547SDavid du Colombier 			s = lookup(fields[i], 0);
33*40d01547SDavid du Colombier 			s->type = SXREF;
34*40d01547SDavid du Colombier 			s->subtype = t;
35*40d01547SDavid du Colombier 			if(t == SIMPORT)
36*40d01547SDavid du Colombier 				nimports++;
37*40d01547SDavid du Colombier 			else
38*40d01547SDavid du Colombier 				nexports++;
39*40d01547SDavid du Colombier 		}
40*40d01547SDavid du Colombier 	}
41*40d01547SDavid du Colombier 	Bterm(b);
42*40d01547SDavid du Colombier }
43*40d01547SDavid du Colombier 
44*40d01547SDavid du Colombier void
undefsym(Sym * s)45*40d01547SDavid du Colombier undefsym(Sym *s)
46*40d01547SDavid du Colombier {
47*40d01547SDavid du Colombier 	int n;
48*40d01547SDavid du Colombier 
49*40d01547SDavid du Colombier 	n = imports;
50*40d01547SDavid du Colombier 	if(s->value != 0)
51*40d01547SDavid du Colombier 		diag("value != 0 on SXREF");
52*40d01547SDavid du Colombier 	if(n >= 1<<Rindex)
53*40d01547SDavid du Colombier 		diag("import index %d out of range", n);
54*40d01547SDavid du Colombier 	s->value = n<<Roffset;
55*40d01547SDavid du Colombier 	s->type = SUNDEF;
56*40d01547SDavid du Colombier 	imports++;
57*40d01547SDavid du Colombier }
58*40d01547SDavid du Colombier 
59*40d01547SDavid du Colombier void
zerosig(char * sp)60*40d01547SDavid du Colombier zerosig(char *sp)
61*40d01547SDavid du Colombier {
62*40d01547SDavid du Colombier 	Sym *s;
63*40d01547SDavid du Colombier 
64*40d01547SDavid du Colombier 	s = lookup(sp, 0);
65*40d01547SDavid du Colombier 	s->sig = 0;
66*40d01547SDavid du Colombier }
67*40d01547SDavid du Colombier 
68*40d01547SDavid du Colombier void
import(void)69*40d01547SDavid du Colombier import(void)
70*40d01547SDavid du Colombier {
71*40d01547SDavid du Colombier 	int i;
72*40d01547SDavid du Colombier 	Sym *s;
73*40d01547SDavid du Colombier 
74*40d01547SDavid du Colombier 	for(i = 0; i < NHASH; i++)
75*40d01547SDavid du Colombier 		for(s = hash[i]; s != S; s = s->link)
76*40d01547SDavid du Colombier 			if(s->sig != 0 && s->type == SXREF && (nimports == 0 || s->subtype == SIMPORT)){
77*40d01547SDavid du Colombier 				undefsym(s);
78*40d01547SDavid du Colombier 				Bprint(&bso, "IMPORT: %s sig=%lux v=%lld\n", s->name, s->sig, (vlong)s->value);
79*40d01547SDavid du Colombier 			}
80*40d01547SDavid du Colombier }
81*40d01547SDavid du Colombier 
82*40d01547SDavid du Colombier void
ckoff(Sym * s,long v)83*40d01547SDavid du Colombier ckoff(Sym *s, long v)
84*40d01547SDavid du Colombier {
85*40d01547SDavid du Colombier 	if(v < 0 || v >= 1<<Roffset)
86*40d01547SDavid du Colombier 		diag("relocation offset %ld for %s out of range", v, s->name);
87*40d01547SDavid du Colombier }
88*40d01547SDavid du Colombier 
89*40d01547SDavid du Colombier static Prog*
newdata(Sym * s,int o,int w,int t)90*40d01547SDavid du Colombier newdata(Sym *s, int o, int w, int t)
91*40d01547SDavid du Colombier {
92*40d01547SDavid du Colombier 	Prog *p;
93*40d01547SDavid du Colombier 
94*40d01547SDavid du Colombier 	p = prg();
95*40d01547SDavid du Colombier 	p->link = datap;
96*40d01547SDavid du Colombier 	datap = p;
97*40d01547SDavid du Colombier 	p->as = ADATA;
98*40d01547SDavid du Colombier 	p->reg = w;
99*40d01547SDavid du Colombier 	p->from.type = D_OREG;
100*40d01547SDavid du Colombier 	p->from.name = t;
101*40d01547SDavid du Colombier 	p->from.sym = s;
102*40d01547SDavid du Colombier 	p->from.offset = o;
103*40d01547SDavid du Colombier 	p->to.type = D_CONST;
104*40d01547SDavid du Colombier 	p->to.name = D_NONE;
105*40d01547SDavid du Colombier 	return p;
106*40d01547SDavid du Colombier }
107*40d01547SDavid du Colombier 
108*40d01547SDavid du Colombier void
export(void)109*40d01547SDavid du Colombier export(void)
110*40d01547SDavid du Colombier {
111*40d01547SDavid du Colombier 	int i, j, n, off, nb, sv, ne;
112*40d01547SDavid du Colombier 	Sym *s, *et, *str, **esyms;
113*40d01547SDavid du Colombier 	Prog *p;
114*40d01547SDavid du Colombier 	char buf[NSNAME], *t;
115*40d01547SDavid du Colombier 
116*40d01547SDavid du Colombier 	n = 0;
117*40d01547SDavid du Colombier 	for(i = 0; i < NHASH; i++)
118*40d01547SDavid du Colombier 		for(s = hash[i]; s != S; s = s->link)
119*40d01547SDavid du Colombier 			if(s->sig != 0 && s->type != SXREF && s->type != SUNDEF && (nexports == 0 || s->subtype == SEXPORT))
120*40d01547SDavid du Colombier 				n++;
121*40d01547SDavid du Colombier 	esyms = malloc(n*sizeof(Sym*));
122*40d01547SDavid du Colombier 	ne = n;
123*40d01547SDavid du Colombier 	n = 0;
124*40d01547SDavid du Colombier 	for(i = 0; i < NHASH; i++)
125*40d01547SDavid du Colombier 		for(s = hash[i]; s != S; s = s->link)
126*40d01547SDavid du Colombier 			if(s->sig != 0 && s->type != SXREF && s->type != SUNDEF && (nexports == 0 || s->subtype == SEXPORT))
127*40d01547SDavid du Colombier 				esyms[n++] = s;
128*40d01547SDavid du Colombier 	for(i = 0; i < ne-1; i++)
129*40d01547SDavid du Colombier 		for(j = i+1; j < ne; j++)
130*40d01547SDavid du Colombier 			if(strcmp(esyms[i]->name, esyms[j]->name) > 0){
131*40d01547SDavid du Colombier 				s = esyms[i];
132*40d01547SDavid du Colombier 				esyms[i] = esyms[j];
133*40d01547SDavid du Colombier 				esyms[j] = s;
134*40d01547SDavid du Colombier 			}
135*40d01547SDavid du Colombier 
136*40d01547SDavid du Colombier 	nb = 0;
137*40d01547SDavid du Colombier 	off = 0;
138*40d01547SDavid du Colombier 	et = lookup(EXPTAB, 0);
139*40d01547SDavid du Colombier 	if(et->type != 0 && et->type != SXREF)
140*40d01547SDavid du Colombier 		diag("%s already defined", EXPTAB);
141*40d01547SDavid du Colombier 	et->type = SDATA;
142*40d01547SDavid du Colombier 	str = lookup(".string", 0);
143*40d01547SDavid du Colombier 	if(str->type == 0)
144*40d01547SDavid du Colombier 		str->type = SDATA;
145*40d01547SDavid du Colombier 	sv = str->value;
146*40d01547SDavid du Colombier 	for(i = 0; i < ne; i++){
147*40d01547SDavid du Colombier 		s = esyms[i];
148*40d01547SDavid du Colombier 		Bprint(&bso, "EXPORT: %s sig=%lux t=%d\n", s->name, s->sig, s->type);
149*40d01547SDavid du Colombier 
150*40d01547SDavid du Colombier 		/* signature */
151*40d01547SDavid du Colombier 		p = newdata(et, off, sizeof(long), D_EXTERN);
152*40d01547SDavid du Colombier 		off += sizeof(long);
153*40d01547SDavid du Colombier 		p->to.offset = s->sig;
154*40d01547SDavid du Colombier 
155*40d01547SDavid du Colombier 		/* address */
156*40d01547SDavid du Colombier 		p = newdata(et, off, sizeof(long), D_EXTERN);
157*40d01547SDavid du Colombier 		off += sizeof(long);
158*40d01547SDavid du Colombier 		p->to.name = D_EXTERN;
159*40d01547SDavid du Colombier 		p->to.sym = s;
160*40d01547SDavid du Colombier 
161*40d01547SDavid du Colombier 		/* string */
162*40d01547SDavid du Colombier 		t = s->name;
163*40d01547SDavid du Colombier 		n = strlen(t)+1;
164*40d01547SDavid du Colombier 		for(;;){
165*40d01547SDavid du Colombier 			buf[nb++] = *t;
166*40d01547SDavid du Colombier 			sv++;
167*40d01547SDavid du Colombier 			if(nb >= NSNAME){
168*40d01547SDavid du Colombier 				p = newdata(str, sv-NSNAME, NSNAME, D_STATIC);
169*40d01547SDavid du Colombier 				p->to.type = D_SCONST;
170*40d01547SDavid du Colombier 				p->to.sval = malloc(NSNAME);
171*40d01547SDavid du Colombier 				memmove(p->to.sval, buf, NSNAME);
172*40d01547SDavid du Colombier 				nb = 0;
173*40d01547SDavid du Colombier 			}
174*40d01547SDavid du Colombier 			if(*t++ == 0)
175*40d01547SDavid du Colombier 				break;
176*40d01547SDavid du Colombier 		}
177*40d01547SDavid du Colombier 
178*40d01547SDavid du Colombier 		/* name */
179*40d01547SDavid du Colombier 		p = newdata(et, off, sizeof(long), D_EXTERN);
180*40d01547SDavid du Colombier 		off += sizeof(long);
181*40d01547SDavid du Colombier 		p->to.name = D_STATIC;
182*40d01547SDavid du Colombier 		p->to.sym = str;
183*40d01547SDavid du Colombier 		p->to.offset = sv-n;
184*40d01547SDavid du Colombier 	}
185*40d01547SDavid du Colombier 
186*40d01547SDavid du Colombier 	if(nb > 0){
187*40d01547SDavid du Colombier 		p = newdata(str, sv-nb, nb, D_STATIC);
188*40d01547SDavid du Colombier 		p->to.type = D_SCONST;
189*40d01547SDavid du Colombier 		p->to.sval = malloc(NSNAME);
190*40d01547SDavid du Colombier 		memmove(p->to.sval, buf, nb);
191*40d01547SDavid du Colombier 	}
192*40d01547SDavid du Colombier 
193*40d01547SDavid du Colombier 	for(i = 0; i < 3; i++){
194*40d01547SDavid du Colombier 		newdata(et, off, sizeof(long), D_EXTERN);
195*40d01547SDavid du Colombier 		off += sizeof(long);
196*40d01547SDavid du Colombier 	}
197*40d01547SDavid du Colombier 	et->value = off;
198*40d01547SDavid du Colombier 	if(sv == 0)
199*40d01547SDavid du Colombier 		sv = 1;
200*40d01547SDavid du Colombier 	str->value = sv;
201*40d01547SDavid du Colombier 	exports = ne;
202*40d01547SDavid du Colombier 	free(esyms);
203*40d01547SDavid du Colombier }
204