xref: /plan9-contrib/sys/src/cmd/ld/sub.c (revision 40d015479ed36701ae6dcfd8814f849fc6285e8d)
1 #include	"l.h"
2 
3 static	usize	nhunk;
4 static	usize	tothunk;
5 static	char*	hunk;
6 
7 void
diag(char * fmt,...)8 diag(char *fmt, ...)
9 {
10 	char buf[STRINGSZ], *tn;
11 	va_list arg;
12 
13 	tn = "??none??";
14 	if(curtext != P && curtext->from.sym != S)
15 		tn = curtext->from.sym->name;
16 	va_start(arg, fmt);
17 	vseprint(buf, buf+sizeof(buf), fmt, arg);
18 	va_end(arg);
19 	print("%s: %s\n", tn, buf);
20 
21 	nerrors++;
22 	if(nerrors > 10) {
23 		print("too many errors\n");
24 		errorexit();
25 	}
26 }
27 
28 void
errorexit(void)29 errorexit(void)
30 {
31 
32 	if(nerrors) {
33 		if(cout >= 0)
34 			remove(outfile);
35 		exits("error");
36 	}
37 	exits(0);
38 }
39 
40 void
prasm(Prog * p)41 prasm(Prog *p)
42 {
43 	print("%P\n", p);
44 }
45 
46 int
Sconv(Fmt * fp)47 Sconv(Fmt *fp)
48 {
49 	int i, c;
50 	char str[STRINGSZ], *p, *a;
51 
52 	a = va_arg(fp->args, char*);
53 	p = str;
54 	for(i=0; i<sizeof(long); i++) {
55 		c = a[i] & 0xff;
56 		if(c >= 'a' && c <= 'z' ||
57 		   c >= 'A' && c <= 'Z' ||
58 		   c >= '0' && c <= '9' ||
59 		   c == ' ' || c == '%') {
60 			*p++ = c;
61 			continue;
62 		}
63 		*p++ = '\\';
64 		switch(c) {
65 		case 0:
66 			*p++ = 'z';
67 			continue;
68 		case '\\':
69 		case '"':
70 			*p++ = c;
71 			continue;
72 		case '\n':
73 			*p++ = 'n';
74 			continue;
75 		case '\t':
76 			*p++ = 't';
77 			continue;
78 		}
79 		*p++ = (c>>6) + '0';
80 		*p++ = ((c>>3) & 7) + '0';
81 		*p++ = (c & 7) + '0';
82 	}
83 	*p = 0;
84 	return fmtstrcpy(fp, str);
85 }
86 
87 void
nopstat(char * f,Count * c)88 nopstat(char *f, Count *c)
89 {
90 	if(c->outof)
91 	Bprint(&bso, "%s delay %ld/%ld (%.2f)\n", f,
92 		c->outof - c->count, c->outof,
93 		(double)(c->outof - c->count)/c->outof);
94 }
95 
96 void
xdefine(char * p,int t,vlong v)97 xdefine(char *p, int t, vlong v)
98 {
99 	Sym *s;
100 
101 	s = lookup(p, 0);
102 	if(s->type == 0 || s->type == SXREF) {
103 		s->type = t;
104 		s->value = v;
105 	}
106 }
107 
108 void
undef(void)109 undef(void)
110 {
111 	int i;
112 	Sym *s;
113 
114 	for(i=0; i<NHASH; i++)
115 	for(s = hash[i]; s != S; s = s->link)
116 		if(s->type == SXREF)
117 			diag("%s: not defined", s->name);
118 }
119 
120 vlong
atolwhex(char * s)121 atolwhex(char *s)
122 {
123 	vlong n;
124 	int f;
125 
126 	n = 0;
127 	f = 0;
128 	while(*s == ' ' || *s == '\t')
129 		s++;
130 	if(*s == '-' || *s == '+') {
131 		if(*s++ == '-')
132 			f = 1;
133 		while(*s == ' ' || *s == '\t')
134 			s++;
135 	}
136 	if(s[0]=='0' && s[1]){
137 		if(s[1]=='x' || s[1]=='X'){
138 			s += 2;
139 			for(;;){
140 				if(*s >= '0' && *s <= '9')
141 					n = n*16 + *s++ - '0';
142 				else if(*s >= 'a' && *s <= 'f')
143 					n = n*16 + *s++ - 'a' + 10;
144 				else if(*s >= 'A' && *s <= 'F')
145 					n = n*16 + *s++ - 'A' + 10;
146 				else
147 					break;
148 			}
149 		} else
150 			while(*s >= '0' && *s <= '7')
151 				n = n*8 + *s++ - '0';
152 	} else
153 		while(*s >= '0' && *s <= '9')
154 			n = n*10 + *s++ - '0';
155 	if(f)
156 		n = -n;
157 	return n;
158 }
159 
160 vlong
rnd(vlong v,long r)161 rnd(vlong v, long r)
162 {
163 	long c;
164 
165 	if(r <= 0)
166 		return v;
167 	v += r - 1;
168 	c = v % r;
169 	if(c < 0)
170 		c += r;
171 	v -= c;
172 	return v;
173 }
174 
175 Prog*
prg(void)176 prg(void)
177 {
178 	Prog *p;
179 
180 	while(nhunk < sizeof(Prog))
181 		gethunk();
182 	p = (Prog*)hunk;
183 	nhunk -= sizeof(Prog);
184 	hunk += sizeof(Prog);
185 
186 	*p = zprg;
187 	return p;
188 }
189 
190 void*
halloc(usize n)191 halloc(usize n)
192 {
193 	void *p;
194 
195 	n = (n+7)&~7;
196 	while(nhunk < n)
197 		gethunk();
198 	p = hunk;
199 	nhunk -= n;
200 	hunk += n;
201 	return p;
202 }
203 
204 void
gethunk(void)205 gethunk(void)
206 {
207 	char *h;
208 	long nh;
209 
210 	nh = NHUNK;
211 	if(tothunk >= 5L*NHUNK) {
212 		nh = 5L*NHUNK;
213 		if(tothunk >= 25L*NHUNK)
214 			nh = 25L*NHUNK;
215 	}
216 	h = mysbrk(nh);
217 	if(h == (void*)-1) {
218 		diag("out of memory");
219 		errorexit();
220 	}
221 
222 	hunk = h;
223 	nhunk = nh;
224 	tothunk += nh;
225 }
226 
227 long
hunkspace(void)228 hunkspace(void)
229 {
230 	return tothunk;
231 }
232 
233 void
strnput(char * s,int n)234 strnput(char *s, int n)
235 {
236 	for(; *s; s++){
237 		cput(*s);
238 		n--;
239 	}
240 	for(; n > 0; n--)
241 		cput(0);
242 }
243 
244 void
cput(int c)245 cput(int c)
246 {
247 	cbp[0] = c;
248 	cbp++;
249 	cbc--;
250 	if(cbc <= 0)
251 		cflush();
252 }
253 
254 void
cflush(void)255 cflush(void)
256 {
257 	int n;
258 
259 	n = sizeof(buf.cbuf) - cbc;
260 	if(n)
261 		write(cout, buf.cbuf, n);
262 	cbp = buf.cbuf;
263 	cbc = sizeof(buf.cbuf);
264 }
265