changelog shortlog tags branches files raw gz bz2 help

Mercurial > hg > plan9front / changeset: [125678kqv][cl]: fix sprint() and strcpy() buffer overflows

changeset 4275: d1102fefd6c1
parent 4274: bb53daa30bfa
child 4276: cecda40aea12
author: cinap_lenrek@felloff.net
date: Tue, 17 Feb 2015 22:13:35 +0100
files: sys/src/cmd/1c/list.c sys/src/cmd/1l/list.c sys/src/cmd/1l/obj.c sys/src/cmd/2c/list.c sys/src/cmd/2l/list.c sys/src/cmd/2l/obj.c sys/src/cmd/5c/list.c sys/src/cmd/5l/list.c sys/src/cmd/5l/obj.c sys/src/cmd/6c/list.c sys/src/cmd/6l/list.c sys/src/cmd/6l/obj.c sys/src/cmd/7c/list.c sys/src/cmd/7l/list.c sys/src/cmd/7l/obj.c sys/src/cmd/7l/pass.c sys/src/cmd/8c/list.c sys/src/cmd/8l/list.c sys/src/cmd/8l/obj.c sys/src/cmd/kc/list.c sys/src/cmd/kl/list.c sys/src/cmd/kl/obj.c sys/src/cmd/kl/pass.c sys/src/cmd/qc/list.c sys/src/cmd/ql/list.c sys/src/cmd/ql/obj.c sys/src/cmd/ql/pass.c sys/src/cmd/vc/list.c sys/src/cmd/vl/list.c sys/src/cmd/vl/obj.c sys/src/cmd/vl/pass.c
description: [125678kqv][cl]: fix sprint() and strcpy() buffer overflows
     1.1--- a/sys/src/cmd/1c/list.c
     1.2+++ b/sys/src/cmd/1c/list.c
     1.3@@ -20,20 +20,18 @@ Bconv(Fmt *fp)
     1.4 	Bits bits;
     1.5 	int i;
     1.6 
     1.7-	str[0] = 0;
     1.8+	memset(str, 0, sizeof str);
     1.9 	bits = va_arg(fp->args, Bits);
    1.10 	while(bany(&bits)) {
    1.11 		i = bnum(bits);
    1.12 		if(str[0])
    1.13-			strcat(str, " ");
    1.14+			strncat(str, " ", sizeof str - 1);
    1.15 		if(var[i].sym == S) {
    1.16-			sprint(ss, "$%ld", var[i].offset);
    1.17+			snprint(ss, sizeof ss, "$%ld", var[i].offset);
    1.18 			s = ss;
    1.19 		} else
    1.20 			s = var[i].sym->name;
    1.21-		if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
    1.22-			break;
    1.23-		strcat(str, s);
    1.24+		strncat(str, s, sizeof str - 1);
    1.25 		bits.b[i/32] &= ~(1L << (i%32));
    1.26 	}
    1.27 	return fmtstrcpy(fp, str);
    1.28@@ -42,15 +40,13 @@ Bconv(Fmt *fp)
    1.29 int
    1.30 Pconv(Fmt *fp)
    1.31 {
    1.32-	char str[STRINGSZ], s[20];
    1.33+	char str[STRINGSZ];
    1.34 	Prog *p;
    1.35 
    1.36 	p = va_arg(fp->args, Prog*);
    1.37-	sprint(str, "	%A	%D,%D", p->as, &p->from, &p->to);
    1.38-	if(p->from.field) {
    1.39-		sprint(s, ",%d,%d", p->to.field, p->from.field);
    1.40-		strcat(str, s);
    1.41-	}
    1.42+	snprint(str, sizeof str, "	%A	%D,%D", p->as, &p->from, &p->to);
    1.43+	if(p->from.field)
    1.44+		return fmtprint(fp, "%s,%d,%d", str, p->to.field, p->from.field);
    1.45 	return fmtstrcpy(fp, str);
    1.46 }
    1.47 
    1.48@@ -66,7 +62,7 @@ Aconv(Fmt *fp)
    1.49 int
    1.50 Dconv(Fmt *fp)
    1.51 {
    1.52-	char str[40], s[20];
    1.53+	char str[40];
    1.54 	Adr *a;
    1.55 	int i, j;
    1.56 	long d;
    1.57@@ -80,26 +76,26 @@ Dconv(Fmt *fp)
    1.58 		a->offset = 0;
    1.59 		switch(j) {
    1.60 		case I_INDINC:
    1.61-			sprint(str, "(%D)+", a);
    1.62+			snprint(str, sizeof str, "(%D)+", a);
    1.63 			break;
    1.64 
    1.65 		case I_INDDEC:
    1.66-			sprint(str, "-(%D)", a);
    1.67+			snprint(str, sizeof str, "-(%D)", a);
    1.68 			break;
    1.69 
    1.70 		case I_INDIR:
    1.71 			if(a->type == D_CONST)
    1.72-				sprint(str, "%ld", d);
    1.73+				snprint(str, sizeof str, "%ld", d);
    1.74 			else
    1.75 			if(d)
    1.76-				sprint(str, "%ld(%D)", d, a);
    1.77+				snprint(str, sizeof str, "%ld(%D)", d, a);
    1.78 			else
    1.79-				sprint(str, "(%D)", a);
    1.80+				snprint(str, sizeof str, "(%D)", a);
    1.81 			break;
    1.82 
    1.83 		case I_ADDR:
    1.84 			a->offset = d;
    1.85-			sprint(str, "$%D", a);
    1.86+			snprint(str, sizeof str, "$%D", a);
    1.87 			break;
    1.88 		}
    1.89 		a->type = i;
    1.90@@ -109,7 +105,7 @@ Dconv(Fmt *fp)
    1.91 	switch(i) {
    1.92 
    1.93 	default:
    1.94-		sprint(str, "%R", i);
    1.95+		snprint(str, sizeof str, "%R", i);
    1.96 		break;
    1.97 
    1.98 	case D_NONE:
    1.99@@ -117,45 +113,43 @@ Dconv(Fmt *fp)
   1.100 		break;
   1.101 
   1.102 	case D_BRANCH:
   1.103-		sprint(str, "%ld(PC)", a->offset-pc);
   1.104+		snprint(str, sizeof str, "%ld(PC)", a->offset-pc);
   1.105 		break;
   1.106 
   1.107 	case D_EXTERN:
   1.108-		sprint(str, "%s+%ld(SB)", a->sym->name, a->offset);
   1.109+		snprint(str, sizeof str, "%s+%ld(SB)", a->sym->name, a->offset);
   1.110 		break;
   1.111 
   1.112 	case D_STATIC:
   1.113-		sprint(str, "%s<>+%ld(SB)", a->sym->name, a->offset);
   1.114+		snprint(str, sizeof str, "%s<>+%ld(SB)", a->sym->name, a->offset);
   1.115 		break;
   1.116 
   1.117 	case D_AUTO:
   1.118-		sprint(str, "%s-%ld(SP)", a->sym->name, -a->offset);
   1.119+		snprint(str, sizeof str, "%s-%ld(SP)", a->sym->name, -a->offset);
   1.120 		break;
   1.121 
   1.122 	case D_PARAM:
   1.123-		sprint(str, "%s+%ld(FP)", a->sym->name, a->offset);
   1.124+		snprint(str, sizeof str, "%s+%ld(FP)", a->sym->name, a->offset);
   1.125 		break;
   1.126 
   1.127 	case D_CONST:
   1.128-		sprint(str, "$%ld", a->offset);
   1.129+		snprint(str, sizeof str, "$%ld", a->offset);
   1.130 		break;
   1.131 
   1.132 	case D_STACK:
   1.133-		sprint(str, "TOS+%ld", a->offset);
   1.134+		snprint(str, sizeof str, "TOS+%ld", a->offset);
   1.135 		break;
   1.136 
   1.137 	case D_FCONST:
   1.138-		sprint(str, "$%.17e", a->dval);
   1.139+		snprint(str, sizeof str, "$%.17e", a->dval);
   1.140 		goto out;
   1.141 
   1.142 	case D_SCONST:
   1.143-		sprint(str, "$\"%S\"", a->sval);
   1.144+		snprint(str, sizeof str, "$\"%S\"", a->sval);
   1.145 		goto out;
   1.146 	}
   1.147-	if(a->displace) {
   1.148-		sprint(s, "/%ld", a->displace);
   1.149-		strcat(str, s);
   1.150-	}
   1.151+	if(a->displace)
   1.152+		return fmtprint(fp, "%s/%ld", str, a->displace);
   1.153 out:
   1.154 	return fmtstrcpy(fp, str);
   1.155 }
   1.156@@ -168,113 +162,113 @@ Rconv(Fmt *fp)
   1.157 
   1.158 	r = va_arg(fp->args, int);
   1.159 	if(r >= D_R0 && r < D_R0+NREG)
   1.160-		sprint(str, "R%d", r-D_R0);
   1.161+		snprint(str, sizeof str, "R%d", r-D_R0);
   1.162 	else
   1.163 	if(r >= D_A0 && r < D_A0+NREG)
   1.164-		sprint(str, "A%d", r-D_A0);
   1.165+		snprint(str, sizeof str, "A%d", r-D_A0);
   1.166 	else
   1.167 	if(r >= D_F0 && r < D_F0+NREG)
   1.168-		sprint(str, "F%d", r-D_F0);
   1.169+		snprint(str, sizeof str, "F%d", r-D_F0);
   1.170 	else
   1.171 	switch(r) {
   1.172 
   1.173 	default:
   1.174-		sprint(str, "gok(%d)", r);
   1.175+		snprint(str, sizeof str, "gok(%d)", r);
   1.176 		break;
   1.177 
   1.178 	case D_NONE:
   1.179-		sprint(str, "NONE");
   1.180+		snprint(str, sizeof str, "NONE");
   1.181 		break;
   1.182 
   1.183 	case D_TOS:
   1.184-		sprint(str, "TOS");
   1.185+		snprint(str, sizeof str, "TOS");
   1.186 		break;
   1.187 
   1.188 	case D_CCR:
   1.189-		sprint(str, "CCR");
   1.190+		snprint(str, sizeof str, "CCR");
   1.191 		break;
   1.192 
   1.193 	case D_SR:
   1.194-		sprint(str, "SR");
   1.195+		snprint(str, sizeof str, "SR");
   1.196 		break;
   1.197 
   1.198 	case D_SFC:
   1.199-		sprint(str, "SFC");
   1.200+		snprint(str, sizeof str, "SFC");
   1.201 		break;
   1.202 
   1.203 	case D_DFC:
   1.204-		sprint(str, "DFC");
   1.205+		snprint(str, sizeof str, "DFC");
   1.206 		break;
   1.207 
   1.208 	case D_CACR:
   1.209-		sprint(str, "CACR");
   1.210+		snprint(str, sizeof str, "CACR");
   1.211 		break;
   1.212 
   1.213 	case D_USP:
   1.214-		sprint(str, "USP");
   1.215+		snprint(str, sizeof str, "USP");
   1.216 		break;
   1.217 
   1.218 	case D_VBR:
   1.219-		sprint(str, "VBR");
   1.220+		snprint(str, sizeof str, "VBR");
   1.221 		break;
   1.222 
   1.223 	case D_CAAR:
   1.224-		sprint(str, "CAAR");
   1.225+		snprint(str, sizeof str, "CAAR");
   1.226 		break;
   1.227 
   1.228 	case D_MSP:
   1.229-		sprint(str, "MSP");
   1.230+		snprint(str, sizeof str, "MSP");
   1.231 		break;
   1.232 
   1.233 	case D_ISP:
   1.234-		sprint(str, "ISP");
   1.235+		snprint(str, sizeof str, "ISP");
   1.236 		break;
   1.237 
   1.238 	case D_TREE:
   1.239-		sprint(str, "TREE");
   1.240+		snprint(str, sizeof str, "TREE");
   1.241 		break;
   1.242 
   1.243 	case D_FPCR:
   1.244-		sprint(str, "FPCR");
   1.245+		snprint(str, sizeof str, "FPCR");
   1.246 		break;
   1.247 
   1.248 	case D_FPSR:
   1.249-		sprint(str, "FPSR");
   1.250+		snprint(str, sizeof str, "FPSR");
   1.251 		break;
   1.252 
   1.253 	case D_FPIAR:
   1.254-		sprint(str, "FPIAR");
   1.255+		snprint(str, sizeof str, "FPIAR");
   1.256 		break;
   1.257 
   1.258 	case D_TC:
   1.259-		sprint(str, "TC");
   1.260+		snprint(str, sizeof str, "TC");
   1.261 		break;
   1.262 
   1.263 	case D_ITT0:
   1.264-		sprint(str, "ITT0");
   1.265+		snprint(str, sizeof str, "ITT0");
   1.266 		break;
   1.267 
   1.268 	case D_ITT1:
   1.269-		sprint(str, "ITT1");
   1.270+		snprint(str, sizeof str, "ITT1");
   1.271 		break;
   1.272 
   1.273 	case D_DTT0:
   1.274-		sprint(str, "DTT0");
   1.275+		snprint(str, sizeof str, "DTT0");
   1.276 		break;
   1.277 
   1.278 	case D_DTT1:
   1.279-		sprint(str, "DTT1");
   1.280+		snprint(str, sizeof str, "DTT1");
   1.281 		break;
   1.282 
   1.283 	case D_MMUSR:
   1.284-		sprint(str, "MMUSR");
   1.285+		snprint(str, sizeof str, "MMUSR");
   1.286 		break;
   1.287 	case D_URP:
   1.288-		sprint(str, "URP");
   1.289+		snprint(str, sizeof str, "URP");
   1.290 		break;
   1.291 
   1.292 	case D_SRP:
   1.293-		sprint(str, "SRP");
   1.294+		snprint(str, sizeof str, "SRP");
   1.295 		break;
   1.296 	}
   1.297 	return fmtstrcpy(fp, str);
     2.1--- a/sys/src/cmd/1l/list.c
     2.2+++ b/sys/src/cmd/1l/list.c
     2.3@@ -16,17 +16,15 @@ static	Prog	*bigP;
     2.4 int
     2.5 Pconv(Fmt *fp)
     2.6 {
     2.7-	char str[STRINGSZ], s[20];
     2.8+	char str[STRINGSZ];
     2.9 	Prog *p;
    2.10 
    2.11 	p = va_arg(fp->args, Prog*);
    2.12 	bigP = p;
    2.13-	sprint(str, "(%ld)	%A	%D,%D",
    2.14+	snprint(str, sizeof str, "(%ld)	%A	%D,%D",
    2.15 		p->line, p->as, &p->from, &p->to);
    2.16-	if(p->from.field) {
    2.17-		sprint(s, ",%d,%d", p->to.field, p->from.field);
    2.18-		strcat(str, s);
    2.19-	}
    2.20+	if(p->from.field)
    2.21+		return fmtprint(fp, "%s,%d,%d", str, p->to.field, p->from.field);
    2.22 	bigP = P;
    2.23 	return fmtstrcpy(fp, str);
    2.24 }
    2.25@@ -34,14 +32,13 @@ Pconv(Fmt *fp)
    2.26 int
    2.27 Aconv(Fmt *fp)
    2.28 {
    2.29-
    2.30 	return fmtstrcpy(fp, anames[va_arg(fp->args, int)]);
    2.31 }
    2.32 
    2.33 int
    2.34 Dconv(Fmt *fp)
    2.35 {
    2.36-	char str[40], s[20];
    2.37+	char str[40];
    2.38 	Adr *a;
    2.39 	int i, j;
    2.40 	long d;
    2.41@@ -55,23 +52,23 @@ Dconv(Fmt *fp)
    2.42 		a->offset = 0;
    2.43 		switch(j) {
    2.44 		case I_INDINC:
    2.45-			sprint(str, "(%D)+", a);
    2.46+			snprint(str, sizeof str, "(%D)+", a);
    2.47 			break;
    2.48 
    2.49 		case I_INDDEC:
    2.50-			sprint(str, "-(%D)", a);
    2.51+			snprint(str, sizeof str, "-(%D)", a);
    2.52 			break;
    2.53 
    2.54 		case I_INDIR:
    2.55 			if(d)
    2.56-				sprint(str, "%ld(%D)", d, a);
    2.57+				snprint(str, sizeof str, "%ld(%D)", d, a);
    2.58 			else
    2.59-				sprint(str, "(%D)", a);
    2.60+				snprint(str, sizeof str, "(%D)", a);
    2.61 			break;
    2.62 
    2.63 		case I_ADDR:
    2.64 			a->offset = d;
    2.65-			sprint(str, "$%D", a);
    2.66+			snprint(str, sizeof str, "$%D", a);
    2.67 			break;
    2.68 		}
    2.69 		a->type = i;
    2.70@@ -81,7 +78,7 @@ Dconv(Fmt *fp)
    2.71 	switch(i) {
    2.72 
    2.73 	default:
    2.74-		sprint(str, "%R", i);
    2.75+		snprint(str, sizeof str, "%R", i);
    2.76 		break;
    2.77 
    2.78 	case D_NONE:
    2.79@@ -91,58 +88,56 @@ Dconv(Fmt *fp)
    2.80 	case D_BRANCH:
    2.81 		if(bigP != P && bigP->pcond != P)
    2.82 			if(a->sym != S)
    2.83-				sprint(str, "%lux+%s", bigP->pcond->pc,
    2.84+				snprint(str, sizeof str, "%lux+%s", bigP->pcond->pc,
    2.85 					a->sym->name);
    2.86 			else
    2.87-				sprint(str, "%lux", bigP->pcond->pc);
    2.88+				snprint(str, sizeof str, "%lux", bigP->pcond->pc);
    2.89 		else
    2.90-			sprint(str, "%ld(PC)", a->offset);
    2.91+			snprint(str, sizeof str, "%ld(PC)", a->offset);
    2.92 		break;
    2.93 
    2.94 	case D_EXTERN:
    2.95-		sprint(str, "%s+%ld(SB)", a->sym->name, a->offset);
    2.96+		snprint(str, sizeof str, "%s+%ld(SB)", a->sym->name, a->offset);
    2.97 		break;
    2.98 
    2.99 	case D_STATIC:
   2.100-		sprint(str, "%s<%d>+%ld(SB)", a->sym->name,
   2.101+		snprint(str, sizeof str, "%s<%d>+%ld(SB)", a->sym->name,
   2.102 			a->sym->version, a->offset);
   2.103 		break;
   2.104 
   2.105 	case D_AUTO:
   2.106-		sprint(str, "%s+%ld(SP)", a->sym->name, a->offset);
   2.107+		snprint(str, sizeof str, "%s+%ld(SP)", a->sym->name, a->offset);
   2.108 		break;
   2.109 
   2.110 	case D_PARAM:
   2.111 		if(a->sym)
   2.112-			sprint(str, "%s+%ld(FP)", a->sym->name, a->offset);
   2.113+			snprint(str, sizeof str, "%s+%ld(FP)", a->sym->name, a->offset);
   2.114 		else
   2.115-			sprint(str, "%ld(FP)", a->offset);
   2.116+			snprint(str, sizeof str, "%ld(FP)", a->offset);
   2.117 		break;
   2.118 
   2.119 	case D_CONST:
   2.120-		sprint(str, "$%ld", a->offset);
   2.121+		snprint(str, sizeof str, "$%ld", a->offset);
   2.122 		break;
   2.123 
   2.124 	case D_STACK:
   2.125-		sprint(str, "TOS+%ld", a->offset);
   2.126+		snprint(str, sizeof str, "TOS+%ld", a->offset);
   2.127 		break;
   2.128 
   2.129 	case D_QUICK:
   2.130-		sprint(str, "$Q%ld", a->offset);
   2.131+		snprint(str, sizeof str, "$Q%ld", a->offset);
   2.132 		break;
   2.133 
   2.134 	case D_FCONST:
   2.135-		sprint(str, "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l);
   2.136+		snprint(str, sizeof str, "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l);
   2.137 		goto out;
   2.138 
   2.139 	case D_SCONST:
   2.140-		sprint(str, "$\"%S\"", a->scon);
   2.141+		snprint(str, sizeof str, "$\"%S\"", a->scon);
   2.142 		goto out;
   2.143 	}
   2.144-	if(a->displace) {
   2.145-		sprint(s, "/%ld", a->displace);
   2.146-		strcat(str, s);
   2.147-	}
   2.148+	if(a->displace)
   2.149+		return fmtprint(fp, "%s/%ld", str, a->displace);
   2.150 out:
   2.151 	return fmtstrcpy(fp, str);
   2.152 }
   2.153@@ -155,113 +150,113 @@ Rconv(Fmt *fp)
   2.154 
   2.155 	r = va_arg(fp->args, int);
   2.156 	if(r >= D_R0 && r < D_R0+NREG)
   2.157-		sprint(str, "R%d", r-D_R0);
   2.158+		snprint(str, sizeof str, "R%d", r-D_R0);
   2.159 	else
   2.160 	if(r >= D_A0 && r < D_A0+NREG)
   2.161-		sprint(str, "A%d", r-D_A0);
   2.162+		snprint(str, sizeof str, "A%d", r-D_A0);
   2.163 	else
   2.164 	if(r >= D_F0 && r < D_F0+NREG)
   2.165-		sprint(str, "F%d", r-D_F0);
   2.166+		snprint(str, sizeof str, "F%d", r-D_F0);
   2.167 	else
   2.168 	switch(r) {
   2.169 
   2.170 	default:
   2.171-		sprint(str, "gok(%d)", r);
   2.172+		snprint(str, sizeof str, "gok(%d)", r);
   2.173 		break;
   2.174 
   2.175 	case D_NONE:
   2.176-		sprint(str, "NONE");
   2.177+		snprint(str, sizeof str, "NONE");
   2.178 		break;
   2.179 
   2.180 	case D_TOS:
   2.181-		sprint(str, "TOS");
   2.182+		snprint(str, sizeof str, "TOS");
   2.183 		break;
   2.184 
   2.185 	case D_CCR:
   2.186-		sprint(str, "CCR");
   2.187+		snprint(str, sizeof str, "CCR");
   2.188 		break;
   2.189 
   2.190 	case D_SR:
   2.191-		sprint(str, "SR");
   2.192+		snprint(str, sizeof str, "SR");
   2.193 		break;
   2.194 
   2.195 	case D_SFC:
   2.196-		sprint(str, "SFC");
   2.197+		snprint(str, sizeof str, "SFC");
   2.198 		break;
   2.199 
   2.200 	case D_DFC:
   2.201-		sprint(str, "DFC");
   2.202+		snprint(str, sizeof str, "DFC");
   2.203 		break;
   2.204 
   2.205 	case D_CACR:
   2.206-		sprint(str, "CACR");
   2.207+		snprint(str, sizeof str, "CACR");
   2.208 		break;
   2.209 
   2.210 	case D_USP:
   2.211-		sprint(str, "USP");
   2.212+		snprint(str, sizeof str, "USP");
   2.213 		break;
   2.214 
   2.215 	case D_VBR:
   2.216-		sprint(str, "VBR");
   2.217+		snprint(str, sizeof str, "VBR");
   2.218 		break;
   2.219 
   2.220 	case D_CAAR:
   2.221-		sprint(str, "CAAR");
   2.222+		snprint(str, sizeof str, "CAAR");
   2.223 		break;
   2.224 
   2.225 	case D_MSP:
   2.226-		sprint(str, "MSP");
   2.227+		snprint(str, sizeof str, "MSP");
   2.228 		break;
   2.229 
   2.230 	case D_ISP:
   2.231-		sprint(str, "ISP");
   2.232+		snprint(str, sizeof str, "ISP");
   2.233 		break;
   2.234 
   2.235 	case D_FPCR:
   2.236-		sprint(str, "FPCR");
   2.237+		snprint(str, sizeof str, "FPCR");
   2.238 		break;
   2.239 
   2.240 	case D_FPSR:
   2.241-		sprint(str, "FPSR");
   2.242+		snprint(str, sizeof str, "FPSR");
   2.243 		break;
   2.244 
   2.245 	case D_FPIAR:
   2.246-		sprint(str, "FPIAR");
   2.247+		snprint(str, sizeof str, "FPIAR");
   2.248 		break;
   2.249 
   2.250 	case D_TREE:
   2.251-		sprint(str, "TREE");
   2.252+		snprint(str, sizeof str, "TREE");
   2.253 		break;
   2.254 
   2.255 	case D_TC:
   2.256-		sprint(str, "TC");
   2.257+		snprint(str, sizeof str, "TC");
   2.258 		break;
   2.259 
   2.260 	case D_ITT0:
   2.261-		sprint(str, "ITT0");
   2.262+		snprint(str, sizeof str, "ITT0");
   2.263 		break;
   2.264 
   2.265 	case D_ITT1:
   2.266-		sprint(str, "ITT1");
   2.267+		snprint(str, sizeof str, "ITT1");
   2.268 		break;
   2.269 
   2.270 	case D_DTT0:
   2.271-		sprint(str, "DTT0");
   2.272+		snprint(str, sizeof str, "DTT0");
   2.273 		break;
   2.274 
   2.275 	case D_DTT1:
   2.276-		sprint(str, "DTT1");
   2.277+		snprint(str, sizeof str, "DTT1");
   2.278 		break;
   2.279 
   2.280 	case D_MMUSR:
   2.281-		sprint(str, "MMUSR");
   2.282+		snprint(str, sizeof str, "MMUSR");
   2.283 		break;
   2.284 	case D_URP:
   2.285-		sprint(str, "URP");
   2.286+		snprint(str, sizeof str, "URP");
   2.287 		break;
   2.288 
   2.289 	case D_SRP:
   2.290-		sprint(str, "SRP");
   2.291+		snprint(str, sizeof str, "SRP");
   2.292 		break;
   2.293 	}
   2.294 	return fmtstrcpy(fp, str);
     3.1--- a/sys/src/cmd/1l/obj.c
     3.2+++ b/sys/src/cmd/1l/obj.c
     3.3@@ -304,9 +304,7 @@ objfile(char *file)
     3.4 	char *e, *start, *stop;
     3.5 
     3.6 	if(file[0] == '-' && file[1] == 'l') {
     3.7-		sprint(name, "/%s/lib/lib", thestring);
     3.8-		strcat(name, file+2);
     3.9-		strcat(name, ".a");
    3.10+		snprint(name, sizeof name, "/%s/lib/lib%s.a", thestring, file+2);
    3.11 		file = name;
    3.12 	}
    3.13 	if(debug['v'])
    3.14@@ -364,7 +362,7 @@ objfile(char *file)
    3.15 			s = lookup(e+5, 0);
    3.16 			if(s->type != SXREF)
    3.17 				continue;
    3.18-			sprint(pname, "%s(%s)", file, s->name);
    3.19+			snprint(pname, sizeof pname, "%s(%s)", file, s->name);
    3.20 			if(debug['v'])
    3.21 				Bprint(&bso, "%5.2f library: %s\n", cputime(), pname);
    3.22 			Bflush(&bso);
    3.23@@ -524,17 +522,17 @@ addlib(char *obj)
    3.24 		return;
    3.25 
    3.26 	if(histfrog[0]->name[1] == '/') {
    3.27-		sprint(name, "");
    3.28+		name[0] = 0;
    3.29 		i = 1;
    3.30 	} else
    3.31 	if(histfrog[0]->name[1] == '.') {
    3.32-		sprint(name, ".");
    3.33+		snprint(name, sizeof name, ".");
    3.34 		i = 0;
    3.35 	} else {
    3.36 		if(debug['9'])
    3.37-			sprint(name, "/%s/lib", thestring);
    3.38+			snprint(name, sizeof name, "/%s/lib", thestring);
    3.39 		else
    3.40-			sprint(name, "/usr/%clib", thechar);
    3.41+			snprint(name, sizeof name, "/usr/%clib", thechar);
    3.42 		i = 0;
    3.43 	}
    3.44 
     4.1--- a/sys/src/cmd/2c/list.c
     4.2+++ b/sys/src/cmd/2c/list.c
     4.3@@ -31,20 +31,18 @@ Bconv(Fmt *fp)
     4.4 	Bits bits;
     4.5 	int i;
     4.6 
     4.7-	str[0] = 0;
     4.8+	memset(str, 0, sizeof str);
     4.9 	bits = va_arg(fp->args, Bits);
    4.10 	while(bany(&bits)) {
    4.11 		i = bnum(bits);
    4.12 		if(str[0])
    4.13-			strcat(str, " ");
    4.14+			strncat(str, " ", sizeof str - 1);
    4.15 		if(var[i].sym == S) {
    4.16-			sprint(ss, "$%ld", var[i].offset);
    4.17+			snprint(ss, sizeof ss, "$%ld", var[i].offset);
    4.18 			s = ss;
    4.19 		} else
    4.20 			s = var[i].sym->name;
    4.21-		if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
    4.22-			break;
    4.23-		strcat(str, s);
    4.24+		strncat(str, s, sizeof str - 1);
    4.25 		bits.b[i/32] &= ~(1L << (i%32));
    4.26 	}
    4.27 	return fmtstrcpy(fp, str);
    4.28@@ -53,15 +51,13 @@ Bconv(Fmt *fp)
    4.29 int
    4.30 Pconv(Fmt *fp)
    4.31 {
    4.32-	char str[STRINGSZ], s[20];
    4.33+	char str[STRINGSZ];
    4.34 	Prog *p;
    4.35 
    4.36 	p = va_arg(fp->args, Prog*);
    4.37-	sprint(str, "	%A	%D,%D", p->as, &p->from, &p->to);
    4.38-	if(p->from.field) {
    4.39-		sprint(s, ",%d,%d", p->to.field, p->from.field);
    4.40-		strcat(str, s);
    4.41-	}
    4.42+	snprint(str, sizeof str, "	%A	%D,%D", p->as, &p->from, &p->to);
    4.43+	if(p->from.field)
    4.44+		return fmtprint(fp, "%s,%d,%d", str, p->to.field, p->from.field);
    4.45 	return fmtstrcpy(fp, str);
    4.46 }
    4.47 
    4.48@@ -77,20 +73,16 @@ Aconv(Fmt *fp)
    4.49 int
    4.50 Xconv(Fmt *fp)
    4.51 {
    4.52-	char str[20], s[10];
    4.53+	char str[20];
    4.54 	Index x;
    4.55-	int i;
    4.56+	int i, j;
    4.57 
    4.58 	x = va_arg(fp->args, Index);
    4.59 	str[0] = 0;
    4.60 	i = x.o0 & D_MASK;
    4.61-	if(i != D_NONE) {
    4.62-		sprint(str, "(%R.", i);
    4.63-		i = x.o1;
    4.64-		sprint(s, "%c*%c)",
    4.65-			"WWWWLLLL"[i],
    4.66-			"12481248"[i]);
    4.67-		strcat(str, s);
    4.68+	if(i != D_NONE){
    4.69+		j = x.o1;
    4.70+		return fmtprint(fp, "(%R.%c*%c)", i, "WWWWLLLL"[j], "12481248"[j]);
    4.71 	}
    4.72 	return fmtstrcpy(fp, str);
    4.73 }
    4.74@@ -98,7 +90,7 @@ Xconv(Fmt *fp)
    4.75 int
    4.76 Dconv(Fmt *fp)
    4.77 {
    4.78-	char str[40], s[20];
    4.79+	char str[40];
    4.80 	Adr *a;
    4.81 	int i, j;
    4.82 	long d;
    4.83@@ -112,25 +104,25 @@ Dconv(Fmt *fp)
    4.84 		a->displace = 0;
    4.85 		switch(i & I_MASK) {
    4.86 		default:
    4.87-			sprint(str, "???%ld(%D%X)", d, a, indexv(i, j));
    4.88+			snprint(str, sizeof str, "???%ld(%D%X)", d, a, indexv(i, j));
    4.89 			break;
    4.90 
    4.91 		case I_INDEX1:
    4.92-			sprint(str, "%D%X", a, indexv(i, a->scale));
    4.93+			snprint(str, sizeof str, "%D%X", a, indexv(i, a->scale));
    4.94 			break;
    4.95 
    4.96 		case I_INDEX2:
    4.97 			if(d)
    4.98-				sprint(str, "%ld(%D)%X", d, a, indexv(i, j));
    4.99+				snprint(str, sizeof str, "%ld(%D)%X", d, a, indexv(i, j));
   4.100 			else
   4.101-				sprint(str, "(%D)%X", a, indexv(i, j));
   4.102+				snprint(str, sizeof str, "(%D)%X", a, indexv(i, j));
   4.103 			break;
   4.104 
   4.105 		case I_INDEX3:
   4.106 			if(d)
   4.107-				sprint(str, "%ld(%D%X)", d, a, indexv(i, j));
   4.108+				snprint(str, sizeof str, "%ld(%D%X)", d, a, indexv(i, j));
   4.109 			else
   4.110-				sprint(str, "(%D%X)", a, indexv(i, j));
   4.111+				snprint(str, sizeof str, "(%D%X)", a, indexv(i, j));
   4.112 			break;
   4.113 		}
   4.114 		a->displace = d;
   4.115@@ -145,26 +137,26 @@ Dconv(Fmt *fp)
   4.116 		a->offset = 0;
   4.117 		switch(j) {
   4.118 		case I_INDINC:
   4.119-			sprint(str, "(%D)+", a);
   4.120+			snprint(str, sizeof str, "(%D)+", a);
   4.121 			break;
   4.122 
   4.123 		case I_INDDEC:
   4.124-			sprint(str, "-(%D)", a);
   4.125+			snprint(str, sizeof str, "-(%D)", a);
   4.126 			break;
   4.127 
   4.128 		case I_INDIR:
   4.129 			if(a->type == D_CONST)
   4.130-				sprint(str, "%ld", d);
   4.131+				snprint(str, sizeof str, "%ld", d);
   4.132 			else
   4.133 			if(d)
   4.134-				sprint(str, "%ld(%D)", d, a);
   4.135+				snprint(str, sizeof str, "%ld(%D)", d, a);
   4.136 			else
   4.137-				sprint(str, "(%D)", a);
   4.138+				snprint(str, sizeof str, "(%D)", a);
   4.139 			break;
   4.140 
   4.141 		case I_ADDR:
   4.142 			a->offset = d;
   4.143-			sprint(str, "$%D", a);
   4.144+			snprint(str, sizeof str, "$%D", a);
   4.145 			break;
   4.146 		}
   4.147 		a->type = i;
   4.148@@ -174,7 +166,7 @@ Dconv(Fmt *fp)
   4.149 	switch(i) {
   4.150 
   4.151 	default:
   4.152-		sprint(str, "%R", i);
   4.153+		snprint(str, sizeof str, "%R", i);
   4.154 		break;
   4.155 
   4.156 	case D_NONE:
   4.157@@ -182,45 +174,43 @@ Dconv(Fmt *fp)
   4.158 		break;
   4.159 
   4.160 	case D_BRANCH:
   4.161-		sprint(str, "%ld(PC)", a->offset-pc);
   4.162+		snprint(str, sizeof str, "%ld(PC)", a->offset-pc);
   4.163 		break;
   4.164 
   4.165 	case D_EXTERN:
   4.166-		sprint(str, "%s+%ld(SB)", a->sym->name, a->offset);
   4.167+		snprint(str, sizeof str, "%s+%ld(SB)", a->sym->name, a->offset);
   4.168 		break;
   4.169 
   4.170 	case D_STATIC:
   4.171-		sprint(str, "%s<>+%ld(SB)", a->sym->name, a->offset);
   4.172+		snprint(str, sizeof str, "%s<>+%ld(SB)", a->sym->name, a->offset);
   4.173 		break;
   4.174 
   4.175 	case D_AUTO:
   4.176-		sprint(str, "%s-%ld(SP)", a->sym->name, -a->offset);
   4.177+		snprint(str, sizeof str, "%s-%ld(SP)", a->sym->name, -a->offset);
   4.178 		break;
   4.179 
   4.180 	case D_PARAM:
   4.181-		sprint(str, "%s+%ld(FP)", a->sym->name, a->offset);
   4.182+		snprint(str, sizeof str, "%s+%ld(FP)", a->sym->name, a->offset);
   4.183 		break;
   4.184 
   4.185 	case D_CONST:
   4.186-		sprint(str, "$%ld", a->offset);
   4.187+		snprint(str, sizeof str, "$%ld", a->offset);
   4.188 		break;
   4.189 
   4.190 	case D_STACK:
   4.191-		sprint(str, "TOS+%ld", a->offset);
   4.192+		snprint(str, sizeof str, "TOS+%ld", a->offset);
   4.193 		break;
   4.194 
   4.195 	case D_FCONST:
   4.196-		sprint(str, "$%.17e", a->dval);
   4.197+		snprint(str, sizeof str, "$%.17e", a->dval);
   4.198 		goto out;
   4.199 
   4.200 	case D_SCONST:
   4.201-		sprint(str, "$\"%S\"", a->sval);
   4.202+		snprint(str, sizeof str, "$\"%S\"", a->sval);
   4.203 		goto out;
   4.204 	}
   4.205-	if(a->displace) {
   4.206-		sprint(s, "/%ld", a->displace);
   4.207-		strcat(str, s);
   4.208-	}
   4.209+	if(a->displace)
   4.210+		return fmtprint(fp, "%s/%ld", str, a->displace);
   4.211 out:
   4.212 	return fmtstrcpy(fp, str);
   4.213 }
   4.214@@ -233,113 +223,113 @@ Rconv(Fmt *fp)
   4.215 
   4.216 	r = va_arg(fp->args, int);
   4.217 	if(r >= D_R0 && r < D_R0+NREG)
   4.218-		sprint(str, "R%d", r-D_R0);
   4.219+		snprint(str, sizeof str, "R%d", r-D_R0);
   4.220 	else
   4.221 	if(r >= D_A0 && r < D_A0+NREG)
   4.222-		sprint(str, "A%d", r-D_A0);
   4.223+		snprint(str, sizeof str, "A%d", r-D_A0);
   4.224 	else
   4.225 	if(r >= D_F0 && r < D_F0+NREG)
   4.226-		sprint(str, "F%d", r-D_F0);
   4.227+		snprint(str, sizeof str, "F%d", r-D_F0);
   4.228 	else
   4.229 	switch(r) {
   4.230 
   4.231 	default:
   4.232-		sprint(str, "gok(%d)", r);
   4.233+		snprint(str, sizeof str, "gok(%d)", r);
   4.234 		break;
   4.235 
   4.236 	case D_NONE:
   4.237-		sprint(str, "NONE");
   4.238+		snprint(str, sizeof str, "NONE");
   4.239 		break;
   4.240 
   4.241 	case D_TOS:
   4.242-		sprint(str, "TOS");
   4.243+		snprint(str, sizeof str, "TOS");
   4.244 		break;
   4.245 
   4.246 	case D_CCR:
   4.247-		sprint(str, "CCR");
   4.248+		snprint(str, sizeof str, "CCR");
   4.249 		break;
   4.250 
   4.251 	case D_SR:
   4.252-		sprint(str, "SR");
   4.253+		snprint(str, sizeof str, "SR");
   4.254 		break;
   4.255 
   4.256 	case D_SFC:
   4.257-		sprint(str, "SFC");
   4.258+		snprint(str, sizeof str, "SFC");
   4.259 		break;
   4.260 
   4.261 	case D_DFC:
   4.262-		sprint(str, "DFC");
   4.263+		snprint(str, sizeof str, "DFC");
   4.264 		break;
   4.265 
   4.266 	case D_CACR:
   4.267-		sprint(str, "CACR");
   4.268+		snprint(str, sizeof str, "CACR");
   4.269 		break;
   4.270 
   4.271 	case D_USP:
   4.272-		sprint(str, "USP");
   4.273+		snprint(str, sizeof str, "USP");
   4.274 		break;
   4.275 
   4.276 	case D_VBR:
   4.277-		sprint(str, "VBR");
   4.278+		snprint(str, sizeof str, "VBR");
   4.279 		break;
   4.280 
   4.281 	case D_CAAR:
   4.282-		sprint(str, "CAAR");
   4.283+		snprint(str, sizeof str, "CAAR");
   4.284 		break;
   4.285 
   4.286 	case D_MSP:
   4.287-		sprint(str, "MSP");
   4.288+		snprint(str, sizeof str, "MSP");
   4.289 		break;
   4.290 
   4.291 	case D_ISP:
   4.292-		sprint(str, "ISP");
   4.293+		snprint(str, sizeof str, "ISP");
   4.294 		break;
   4.295 
   4.296 	case D_TREE:
   4.297-		sprint(str, "TREE");
   4.298+		snprint(str, sizeof str, "TREE");
   4.299 		break;
   4.300 
   4.301 	case D_FPCR:
   4.302-		sprint(str, "FPCR");
   4.303+		snprint(str, sizeof str, "FPCR");
   4.304 		break;
   4.305 
   4.306 	case D_FPSR:
   4.307-		sprint(str, "FPSR");
   4.308+		snprint(str, sizeof str, "FPSR");
   4.309 		break;
   4.310 
   4.311 	case D_FPIAR:
   4.312-		sprint(str, "FPIAR");
   4.313+		snprint(str, sizeof str, "FPIAR");
   4.314 		break;
   4.315 
   4.316 	case D_TC:
   4.317-		sprint(str, "TC");
   4.318+		snprint(str, sizeof str, "TC");
   4.319 		break;
   4.320 
   4.321 	case D_ITT0:
   4.322-		sprint(str, "ITT0");
   4.323+		snprint(str, sizeof str, "ITT0");
   4.324 		break;
   4.325 
   4.326 	case D_ITT1:
   4.327-		sprint(str, "ITT1");
   4.328+		snprint(str, sizeof str, "ITT1");
   4.329 		break;
   4.330 
   4.331 	case D_DTT0:
   4.332-		sprint(str, "DTT0");
   4.333+		snprint(str, sizeof str, "DTT0");
   4.334 		break;
   4.335 
   4.336 	case D_DTT1:
   4.337-		sprint(str, "DTT1");
   4.338+		snprint(str, sizeof str, "DTT1");
   4.339 		break;
   4.340 
   4.341 	case D_MMUSR:
   4.342-		sprint(str, "MMUSR");
   4.343+		snprint(str, sizeof str, "MMUSR");
   4.344 		break;
   4.345 	case D_URP:
   4.346-		sprint(str, "URP");
   4.347+		snprint(str, sizeof str, "URP");
   4.348 		break;
   4.349 
   4.350 	case D_SRP:
   4.351-		sprint(str, "SRP");
   4.352+		snprint(str, sizeof str, "SRP");
   4.353 		break;
   4.354 	}
   4.355 	return fmtstrcpy(fp, str);
     5.1--- a/sys/src/cmd/2l/list.c
     5.2+++ b/sys/src/cmd/2l/list.c
     5.3@@ -16,17 +16,15 @@ static	Prog	*bigP;
     5.4 int
     5.5 Pconv(Fmt *fp)
     5.6 {
     5.7-	char str[STRINGSZ], s[20];
     5.8+	char str[STRINGSZ];
     5.9 	Prog *p;
    5.10 
    5.11 	p = va_arg(fp->args, Prog*);
    5.12 	bigP = p;
    5.13-	sprint(str, "(%ld)	%A	%D,%D",
    5.14+	snprint(str, sizeof str, "(%ld)	%A	%D,%D",
    5.15 		p->line, p->as, &p->from, &p->to);
    5.16-	if(p->from.field) {
    5.17-		sprint(s, ",%d,%d", p->to.field, p->from.field);
    5.18-		strcat(str, s);
    5.19-	}
    5.20+	if(p->from.field)
    5.21+		return fmtprint(fp, "%s,%d,%d", str, p->to.field, p->from.field);
    5.22 	bigP = P;
    5.23 	return fmtstrcpy(fp, str);
    5.24 }
    5.25@@ -34,26 +32,20 @@ Pconv(Fmt *fp)
    5.26 int
    5.27 Aconv(Fmt *fp)
    5.28 {
    5.29-
    5.30 	return fmtstrcpy(fp, anames[va_arg(fp->args, int)]);
    5.31 }
    5.32 
    5.33 int
    5.34 Xconv(Fmt *fp)
    5.35 {
    5.36-	char str[20], s[10];
    5.37+	char str[30];
    5.38 	int i0, i1;
    5.39 
    5.40 	str[0] = 0;
    5.41 	i0 = va_arg(fp->args, int) & D_MASK;
    5.42 	i1 = va_arg(fp->args, int);
    5.43-	if(i0 != D_NONE) {
    5.44-		sprint(str, "(%R.", i0);
    5.45-		sprint(s, "%c*%c)",
    5.46-			"WWWWLLLL"[i1],
    5.47-			"12481248"[i1]);
    5.48-		strcat(str, s);
    5.49-	}
    5.50+	if(i0 != D_NONE)
    5.51+		snprint(str, sizeof str, "(%R.%c*%c)", i0, "WWWWLLLL"[i1], "12481248"[i1]);
    5.52 	return fmtstrcpy(fp, str);
    5.53 }
    5.54 
    5.55@@ -73,37 +65,38 @@ Dconv(Fmt *fp)
    5.56 		a->displace = 0;
    5.57 		switch(i & I_MASK) {
    5.58 		default:
    5.59-			sprint(str, "???%ld(%D)", d, a);
    5.60+			snprint(str, sizeof str, "???%ld(%D)", d, a);
    5.61 			break;
    5.62 
    5.63 		case I_INDEX1:
    5.64-			sprint(str, "%D", a);
    5.65+			snprint(str, sizeof str, "%D", a);
    5.66 			break;
    5.67 
    5.68 		case I_INDEX2:
    5.69 			if(d)
    5.70-				sprint(str, "%ld(%D)", d, a);
    5.71+				snprint(str, sizeof str, "%ld(%D)", d, a);
    5.72 			else
    5.73-				sprint(str, "(%D)", a);
    5.74+				snprint(str, sizeof str, "(%D)", a);
    5.75 			break;
    5.76 
    5.77 		case I_INDEX3:
    5.78 			if(d)
    5.79-				sprint(str, "%ld(%D", d, a);
    5.80+				snprint(str, sizeof str, "%ld(%D", d, a);
    5.81 			else
    5.82-				sprint(str, "(%D", a);
    5.83+				snprint(str, sizeof str, "(%D", a);
    5.84 			break;
    5.85 		}
    5.86 
    5.87 		if(i != D_NONE) {
    5.88 			j = a->scale & 7;
    5.89-			sprint(strchr(str,0), "(%R.", i);
    5.90-			sprint(strchr(str,0), "%c*%c)",
    5.91-				"WWWWLLLL"[j],
    5.92-				"12481248"[j]);
    5.93+			snprint(s, sizeof s, "(%R.%c*%c)", i, "WWWWLLLL"[j], "12481248"[j]);
    5.94+			strncat(str, s, sizeof str - 1);
    5.95+			str[sizeof str - 1] = 0;
    5.96 		}
    5.97-		if((i & I_MASK) == I_INDEX3)
    5.98-			strcat(str, ")");
    5.99+		if((i & I_MASK) == I_INDEX3){
   5.100+			strncat(str, ")", sizeof str - 1);
   5.101+			str[sizeof str - 1] = 0;
   5.102+		}
   5.103 		a->displace = d;
   5.104 		a->index = i;
   5.105 		goto out;
   5.106@@ -116,23 +109,23 @@ Dconv(Fmt *fp)
   5.107 		a->offset = 0;
   5.108 		switch(j) {
   5.109 		case I_INDINC:
   5.110-			sprint(str, "(%D)+", a);
   5.111+			snprint(str, sizeof str, "(%D)+", a);
   5.112 			break;
   5.113 
   5.114 		case I_INDDEC:
   5.115-			sprint(str, "-(%D)", a);
   5.116+			snprint(str, sizeof str, "-(%D)", a);
   5.117 			break;
   5.118 
   5.119 		case I_INDIR:
   5.120 			if(d)
   5.121-				sprint(str, "%ld(%D)", d, a);
   5.122+				snprint(str, sizeof str, "%ld(%D)", d, a);
   5.123 			else
   5.124-				sprint(str, "(%D)", a);
   5.125+				snprint(str, sizeof str, "(%D)", a);
   5.126 			break;
   5.127 
   5.128 		case I_ADDR:
   5.129 			a->offset = d;
   5.130-			sprint(str, "$%D", a);
   5.131+			snprint(str, sizeof str, "$%D", a);
   5.132 			break;
   5.133 		}
   5.134 		a->type = i;
   5.135@@ -142,7 +135,7 @@ Dconv(Fmt *fp)
   5.136 	switch(i) {
   5.137 
   5.138 	default:
   5.139-		sprint(str, "%R", i);
   5.140+		snprint(str, sizeof str, "%R", i);
   5.141 		break;
   5.142 
   5.143 	case D_NONE:
   5.144@@ -152,58 +145,56 @@ Dconv(Fmt *fp)
   5.145 	case D_BRANCH:
   5.146 		if(bigP != P && bigP->pcond != P)
   5.147 			if(a->sym != S)
   5.148-				sprint(str, "%lux+%s", bigP->pcond->pc,
   5.149+				snprint(str, sizeof str, "%lux+%s", bigP->pcond->pc,
   5.150 					a->sym->name);
   5.151 			else
   5.152-				sprint(str, "%lux", bigP->pcond->pc);
   5.153+				snprint(str, sizeof str, "%lux", bigP->pcond->pc);
   5.154 		else
   5.155-			sprint(str, "%ld(PC)", a->offset);
   5.156+			snprint(str, sizeof str, "%ld(PC)", a->offset);
   5.157 		break;
   5.158 
   5.159 	case D_EXTERN:
   5.160-		sprint(str, "%s+%ld(SB)", a->sym->name, a->offset);
   5.161+		snprint(str, sizeof str, "%s+%ld(SB)", a->sym->name, a->offset);
   5.162 		break;
   5.163 
   5.164 	case D_STATIC:
   5.165-		sprint(str, "%s<%d>+%ld(SB)", a->sym->name,
   5.166+		snprint(str, sizeof str, "%s<%d>+%ld(SB)", a->sym->name,
   5.167 			a->sym->version, a->offset);
   5.168 		break;
   5.169 
   5.170 	case D_AUTO:
   5.171-		sprint(str, "%s+%ld(SP)", a->sym->name, a->offset);
   5.172+		snprint(str, sizeof str, "%s+%ld(SP)", a->sym->name, a->offset);
   5.173 		break;
   5.174 
   5.175 	case D_PARAM:
   5.176 		if(a->sym)
   5.177-			sprint(str, "%s+%ld(FP)", a->sym->name, a->offset);
   5.178+			snprint(str, sizeof str, "%s+%ld(FP)", a->sym->name, a->offset);
   5.179 		else
   5.180-			sprint(str, "%ld(FP)", a->offset);
   5.181+			snprint(str, sizeof str, "%ld(FP)", a->offset);
   5.182 		break;
   5.183 
   5.184 	case D_CONST:
   5.185-		sprint(str, "$%ld", a->offset);
   5.186+		snprint(str, sizeof str, "$%ld", a->offset);
   5.187 		break;
   5.188 
   5.189 	case D_STACK:
   5.190-		sprint(str, "TOS+%ld", a->offset);
   5.191+		snprint(str, sizeof str, "TOS+%ld", a->offset);
   5.192 		break;
   5.193 
   5.194 	case D_QUICK:
   5.195-		sprint(str, "$Q%ld", a->offset);
   5.196+		snprint(str, sizeof str, "$Q%ld", a->offset);
   5.197 		break;
   5.198 
   5.199 	case D_FCONST:
   5.200-		sprint(str, "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l);
   5.201+		snprint(str, sizeof str, "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l);
   5.202 		goto out;
   5.203 
   5.204 	case D_SCONST:
   5.205-		sprint(str, "$\"%S\"", a->scon);
   5.206+		snprint(str, sizeof str, "$\"%S\"", a->scon);
   5.207 		goto out;
   5.208 	}
   5.209-	if(a->displace) {
   5.210-		sprint(s, "/%ld", a->displace);
   5.211-		strcat(str, s);
   5.212-	}
   5.213+	if(a->displace)
   5.214+		return fmtprint(fp, "%s/%ld", str, a->displace);
   5.215 out:
   5.216 	return fmtstrcpy(fp, str);
   5.217 }
   5.218@@ -216,113 +207,113 @@ Rconv(Fmt *fp)
   5.219 
   5.220 	r = va_arg(fp->args, int);
   5.221 	if(r >= D_R0 && r < D_R0+NREG)
   5.222-		sprint(str, "R%d", r-D_R0);
   5.223+		snprint(str, sizeof str, "R%d", r-D_R0);
   5.224 	else
   5.225 	if(r >= D_A0 && r < D_A0+NREG)
   5.226-		sprint(str, "A%d", r-D_A0);
   5.227+		snprint(str, sizeof str, "A%d", r-D_A0);
   5.228 	else
   5.229 	if(r >= D_F0 && r < D_F0+NREG)
   5.230-		sprint(str, "F%d", r-D_F0);
   5.231+		snprint(str, sizeof str, "F%d", r-D_F0);
   5.232 	else
   5.233 	switch(r) {
   5.234 
   5.235 	default:
   5.236-		sprint(str, "gok(%d)", r);
   5.237+		snprint(str, sizeof str, "gok(%d)", r);
   5.238 		break;
   5.239 
   5.240 	case D_NONE:
   5.241-		sprint(str, "NONE");
   5.242+		snprint(str, sizeof str, "NONE");
   5.243 		break;
   5.244 
   5.245 	case D_TOS:
   5.246-		sprint(str, "TOS");
   5.247+		snprint(str, sizeof str, "TOS");
   5.248 		break;
   5.249 
   5.250 	case D_CCR:
   5.251-		sprint(str, "CCR");
   5.252+		snprint(str, sizeof str, "CCR");
   5.253 		break;
   5.254 
   5.255 	case D_SR:
   5.256-		sprint(str, "SR");
   5.257+		snprint(str, sizeof str, "SR");
   5.258 		break;
   5.259 
   5.260 	case D_SFC:
   5.261-		sprint(str, "SFC");
   5.262+		snprint(str, sizeof str, "SFC");
   5.263 		break;
   5.264 
   5.265 	case D_DFC:
   5.266-		sprint(str, "DFC");
   5.267+		snprint(str, sizeof str, "DFC");
   5.268 		break;
   5.269 
   5.270 	case D_CACR:
   5.271-		sprint(str, "CACR");
   5.272+		snprint(str, sizeof str, "CACR");
   5.273 		break;
   5.274 
   5.275 	case D_USP:
   5.276-		sprint(str, "USP");
   5.277+		snprint(str, sizeof str, "USP");
   5.278 		break;
   5.279 
   5.280 	case D_VBR:
   5.281-		sprint(str, "VBR");
   5.282+		snprint(str, sizeof str, "VBR");
   5.283 		break;
   5.284 
   5.285 	case D_CAAR:
   5.286-		sprint(str, "CAAR");
   5.287+		snprint(str, sizeof str, "CAAR");
   5.288 		break;
   5.289 
   5.290 	case D_MSP:
   5.291-		sprint(str, "MSP");
   5.292+		snprint(str, sizeof str, "MSP");
   5.293 		break;
   5.294 
   5.295 	case D_ISP:
   5.296-		sprint(str, "ISP");
   5.297+		snprint(str, sizeof str, "ISP");
   5.298 		break;
   5.299 
   5.300 	case D_FPCR:
   5.301-		sprint(str, "FPCR");
   5.302+		snprint(str, sizeof str, "FPCR");
   5.303 		break;
   5.304 
   5.305 	case D_FPSR:
   5.306-		sprint(str, "FPSR");
   5.307+		snprint(str, sizeof str, "FPSR");
   5.308 		break;
   5.309 
   5.310 	case D_FPIAR:
   5.311-		sprint(str, "FPIAR");
   5.312+		snprint(str, sizeof str, "FPIAR");
   5.313 		break;
   5.314 
   5.315 	case D_TREE:
   5.316-		sprint(str, "TREE");
   5.317+		snprint(str, sizeof str, "TREE");
   5.318 		break;
   5.319 
   5.320 	case D_TC:
   5.321-		sprint(str, "TC");
   5.322+		snprint(str, sizeof str, "TC");
   5.323 		break;
   5.324 
   5.325 	case D_ITT0:
   5.326-		sprint(str, "ITT0");
   5.327+		snprint(str, sizeof str, "ITT0");
   5.328 		break;
   5.329 
   5.330 	case D_ITT1:
   5.331-		sprint(str, "ITT1");
   5.332+		snprint(str, sizeof str, "ITT1");
   5.333 		break;
   5.334 
   5.335 	case D_DTT0:
   5.336-		sprint(str, "DTT0");
   5.337+		snprint(str, sizeof str, "DTT0");
   5.338 		break;
   5.339 
   5.340 	case D_DTT1:
   5.341-		sprint(str, "DTT1");
   5.342+		snprint(str, sizeof str, "DTT1");
   5.343 		break;
   5.344 
   5.345 	case D_MMUSR:
   5.346-		sprint(str, "MMUSR");
   5.347+		snprint(str, sizeof str, "MMUSR");
   5.348 		break;
   5.349 	case D_URP:
   5.350-		sprint(str, "URP");
   5.351+		snprint(str, sizeof str, "URP");
   5.352 		break;
   5.353 
   5.354 	case D_SRP:
   5.355-		sprint(str, "SRP");
   5.356+		snprint(str, sizeof str, "SRP");
   5.357 		break;
   5.358 	}
   5.359 	return fmtstrcpy(fp, str);
     6.1--- a/sys/src/cmd/2l/obj.c
     6.2+++ b/sys/src/cmd/2l/obj.c
     6.3@@ -308,11 +308,9 @@ objfile(char *file)
     6.4 
     6.5 	if(file[0] == '-' && file[1] == 'l') {
     6.6 		if(debug['9'])
     6.7-			sprint(name, "/%s/lib/lib", thestring);
     6.8+			snprint(name, sizeof name, "/%s/lib/lib%s.a", thestring, file+2);
     6.9 		else
    6.10-			sprint(name, "/usr/%clib/lib", thechar);
    6.11-		strcat(name, file+2);
    6.12-		strcat(name, ".a");
    6.13+			snprint(name, sizeof name, "/usr/%clib/lib%s.a", thechar, file+2);
    6.14 		file = name;
    6.15 	}
    6.16 	if(debug['v'])
    6.17@@ -370,7 +368,7 @@ objfile(char *file)
    6.18 			s = lookup(e+5, 0);
    6.19 			if(s->type != SXREF)
    6.20 				continue;
    6.21-			sprint(pname, "%s(%s)", file, s->name);
    6.22+			snprint(pname, sizeof pname, "%s(%s)", file, s->name);
    6.23 			if(debug['v'])
    6.24 				Bprint(&bso, "%5.2f library: %s\n", cputime(), pname);
    6.25 			Bflush(&bso);
    6.26@@ -539,17 +537,17 @@ addlib(char *obj)
    6.27 		return;
    6.28 
    6.29 	if(histfrog[0]->name[1] == '/') {
    6.30-		sprint(name, "");
    6.31+		name[0] = 0;
    6.32 		i = 1;
    6.33 	} else
    6.34 	if(histfrog[0]->name[1] == '.') {
    6.35-		sprint(name, ".");
    6.36+		snprint(name, sizeof name, ".");
    6.37 		i = 0;
    6.38 	} else {
    6.39 		if(debug['9'])
    6.40-			sprint(name, "/%s/lib", thestring);
    6.41+			snprint(name, sizeof name, "/%s/lib", thestring);
    6.42 		else
    6.43-			sprint(name, "/usr/%clib", thechar);
    6.44+			snprint(name, sizeof name, "/usr/%clib", thechar);
    6.45 		i = 0;
    6.46 	}
    6.47 
     7.1--- a/sys/src/cmd/5c/list.c
     7.2+++ b/sys/src/cmd/5c/list.c
     7.3@@ -21,20 +21,18 @@ Bconv(Fmt *fp)
     7.4 	Bits bits;
     7.5 	int i;
     7.6 
     7.7-	str[0] = 0;
     7.8+	memset(str, 0, sizeof str);
     7.9 	bits = va_arg(fp->args, Bits);
    7.10 	while(bany(&bits)) {
    7.11 		i = bnum(bits);
    7.12 		if(str[0])
    7.13-			strcat(str, " ");
    7.14+			strncat(str, " ", sizeof str - 1);
    7.15 		if(var[i].sym == S) {
    7.16-			sprint(ss, "$%ld", var[i].offset);
    7.17+			snprint(ss, sizeof ss, "$%ld", var[i].offset);
    7.18 			s = ss;
    7.19 		} else
    7.20 			s = var[i].sym->name;
    7.21-		if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
    7.22-			break;
    7.23-		strcat(str, s);
    7.24+		strncat(str, s, sizeof str - 1);
    7.25 		bits.b[i/32] &= ~(1L << (i%32));
    7.26 	}
    7.27 	return fmtstrcpy(fp, str);
    7.28@@ -68,26 +66,26 @@ Pconv(Fmt *fp)
    7.29 		strcat(sc, ".U");
    7.30 	if(a == AMOVM) {
    7.31 		if(p->from.type == D_CONST)
    7.32-			sprint(str, "	%A%s	%R,%D", a, sc, &p->from, &p->to);
    7.33+			snprint(str, sizeof str, "	%A%s	%R,%D", a, sc, &p->from, &p->to);
    7.34 		else
    7.35 		if(p->to.type == D_CONST)
    7.36-			sprint(str, "	%A%s	%D,%R", a, sc, &p->from, &p->to);
    7.37+			snprint(str, sizeof str, "	%A%s	%D,%R", a, sc, &p->from, &p->to);
    7.38 		else
    7.39-			sprint(str, "	%A%s	%D,%D", a, sc, &p->from, &p->to);
    7.40+			snprint(str, sizeof str, "	%A%s	%D,%D", a, sc, &p->from, &p->to);
    7.41 	} else
    7.42 	if(a == ADATA)
    7.43-		sprint(str, "	%A	%D/%d,%D", a, &p->from, p->reg, &p->to);
    7.44+		snprint(str, sizeof str, "	%A	%D/%d,%D", a, &p->from, p->reg, &p->to);
    7.45 	else
    7.46 	if(p->as == ATEXT)
    7.47-		sprint(str, "	%A	%D,%d,%D", a, &p->from, p->reg, &p->to);
    7.48+		snprint(str, sizeof str, "	%A	%D,%d,%D", a, &p->from, p->reg, &p->to);
    7.49 	else
    7.50 	if(p->reg == NREG)
    7.51-		sprint(str, "	%A%s	%D,%D", a, sc, &p->from, &p->to);
    7.52+		snprint(str, sizeof str, "	%A%s	%D,%D", a, sc, &p->from, &p->to);
    7.53 	else
    7.54 	if(p->from.type != D_FREG)
    7.55-		sprint(str, "	%A%s	%D,R%d,%D", a, sc, &p->from, p->reg, &p->to);
    7.56+		snprint(str, sizeof str, "	%A%s	%D,R%d,%D", a, sc, &p->from, p->reg, &p->to);
    7.57 	else
    7.58-		sprint(str, "	%A%s	%D,F%d,%D", a, sc, &p->from, p->reg, &p->to);
    7.59+		snprint(str, sizeof str, "	%A%s	%D,F%d,%D", a, sc, &p->from, p->reg, &p->to);
    7.60 	return fmtstrcpy(fp, str);
    7.61 }
    7.62 
    7.63@@ -116,68 +114,68 @@ Dconv(Fmt *fp)
    7.64 	switch(a->type) {
    7.65 
    7.66 	default:
    7.67-		sprint(str, "GOK-type(%d)", a->type);
    7.68+		snprint(str, sizeof str, "GOK-type(%d)", a->type);
    7.69 		break;
    7.70 
    7.71 	case D_NONE:
    7.72 		str[0] = 0;
    7.73 		if(a->name != D_NONE || a->reg != NREG || a->sym != S)
    7.74-			sprint(str, "%N(R%d)(NONE)", a, a->reg);
    7.75+			snprint(str, sizeof str, "%N(R%d)(NONE)", a, a->reg);
    7.76 		break;
    7.77 
    7.78 	case D_CONST:
    7.79 		if(a->reg != NREG)
    7.80-			sprint(str, "$%N(R%d)", a, a->reg);
    7.81+			snprint(str, sizeof str, "$%N(R%d)", a, a->reg);
    7.82 		else
    7.83-			sprint(str, "$%N", a);
    7.84+			snprint(str, sizeof str, "$%N", a);
    7.85 		break;
    7.86 
    7.87 	case D_SHIFT:
    7.88 		v = a->offset;
    7.89 		op = "<<>>->@>" + (((v>>5) & 3) << 1);
    7.90 		if(v & (1<<4))
    7.91-			sprint(str, "R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15);
    7.92+			snprint(str, sizeof str, "R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15);
    7.93 		else
    7.94-			sprint(str, "R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31);
    7.95+			snprint(str, sizeof str, "R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31);
    7.96 		if(a->reg != NREG)
    7.97-			sprint(str+strlen(str), "(R%d)", a->reg);
    7.98+			snprint(str+strlen(str), sizeof(str)-strlen(str), "(R%d)", a->reg);
    7.99 		break;
   7.100 
   7.101 	case D_OREG:
   7.102 		if(a->reg != NREG)
   7.103-			sprint(str, "%N(R%d)", a, a->reg);
   7.104+			snprint(str, sizeof str, "%N(R%d)", a, a->reg);
   7.105 		else
   7.106-			sprint(str, "%N", a);
   7.107+			snprint(str, sizeof str, "%N", a);
   7.108 		break;
   7.109 
   7.110 	case D_REG:
   7.111-		sprint(str, "R%d", a->reg);
   7.112+		snprint(str, sizeof str, "R%d", a->reg);
   7.113 		if(a->name != D_NONE || a->sym != S)
   7.114-			sprint(str, "%N(R%d)(REG)", a, a->reg);
   7.115+			snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
   7.116 		break;
   7.117 
   7.118 	case D_FREG:
   7.119-		sprint(str, "F%d", a->reg);
   7.120+		snprint(str, sizeof str, "F%d", a->reg);
   7.121 		if(a->name != D_NONE || a->sym != S)
   7.122-			sprint(str, "%N(R%d)(REG)", a, a->reg);
   7.123+			snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
   7.124 		break;
   7.125 
   7.126 	case D_PSR:
   7.127-		sprint(str, "PSR");
   7.128+		snprint(str, sizeof str, "PSR");
   7.129 		if(a->name != D_NONE || a->sym != S)
   7.130-			sprint(str, "%N(PSR)(REG)", a);
   7.131+			snprint(str, sizeof str, "%N(PSR)(REG)", a);
   7.132 		break;
   7.133 
   7.134 	case D_BRANCH:
   7.135-		sprint(str, "%ld(PC)", a->offset-pc);
   7.136+		snprint(str, sizeof str, "%ld(PC)", a->offset-pc);
   7.137 		break;
   7.138 
   7.139 	case D_FCONST:
   7.140-		sprint(str, "$%.17e", a->dval);
   7.141+		snprint(str, sizeof str, "$%.17e", a->dval);
   7.142 		break;
   7.143 
   7.144 	case D_SCONST:
   7.145-		sprint(str, "$\"%S\"", a->sval);
   7.146+		snprint(str, sizeof str, "$\"%S\"", a->sval);
   7.147 		break;
   7.148 	}
   7.149 	return fmtstrcpy(fp, str);
   7.150@@ -191,7 +189,7 @@ Rconv(Fmt *fp)
   7.151 	int i, v;
   7.152 
   7.153 	a = va_arg(fp->args, Adr*);
   7.154-	sprint(str, "GOK-reglist");
   7.155+	snprint(str, sizeof str, "GOK-reglist");
   7.156 	switch(a->type) {
   7.157 	case D_CONST:
   7.158 		if(a->reg != NREG)
   7.159@@ -199,17 +197,17 @@ Rconv(Fmt *fp)
   7.160 		if(a->sym != S)
   7.161 			break;
   7.162 		v = a->offset;
   7.163-		strcpy(str, "");
   7.164+		memset(str, 0, sizeof str);
   7.165 		for(i=0; i<NREG; i++) {
   7.166 			if(v & (1<<i)) {
   7.167 				if(str[0] == 0)
   7.168-					strcat(str, "[R");
   7.169+					strncat(str, "[R", sizeof str - 1);
   7.170 				else
   7.171-					strcat(str, ",R");
   7.172-				sprint(strchr(str, 0), "%d", i);
   7.173+					strncat(str, ",R", sizeof str - 1);
   7.174+				snprint(str+strlen(str), sizeof(str)-strlen(str), "%d", i);
   7.175 			}
   7.176 		}
   7.177-		strcat(str, "]");
   7.178+		strncat(str, "]", sizeof str - 1);
   7.179 	}
   7.180 	return fmtstrcpy(fp, str);
   7.181 }
   7.182@@ -271,32 +269,32 @@ Nconv(Fmt *fp)
   7.183 	a = va_arg(fp->args, Adr*);
   7.184 	s = a->sym;
   7.185 	if(s == S) {
   7.186-		sprint(str, "%ld", a->offset);
   7.187+		snprint(str, sizeof str, "%ld", a->offset);
   7.188 		goto out;
   7.189 	}
   7.190 	switch(a->name) {
   7.191 	default:
   7.192-		sprint(str, "GOK-name(%d)", a->name);
   7.193+		snprint(str, sizeof str, "GOK-name(%d)", a->name);
   7.194 		break;
   7.195 
   7.196 	case D_NONE:
   7.197-		sprint(str, "%ld", a->offset);
   7.198+		snprint(str, sizeof str, "%ld", a->offset);
   7.199 		break;
   7.200 
   7.201 	case D_EXTERN:
   7.202-		sprint(str, "%s+%ld(SB)", s->name, a->offset);
   7.203+		snprint(str, sizeof str, "%s+%ld(SB)", s->name, a->offset);
   7.204 		break;
   7.205 
   7.206 	case D_STATIC:
   7.207-		sprint(str, "%s<>+%ld(SB)", s->name, a->offset);
   7.208+		snprint(str, sizeof str, "%s<>+%ld(SB)", s->name, a->offset);
   7.209 		break;
   7.210 
   7.211 	case D_AUTO:
   7.212-		sprint(str, "%s-%ld(SP)", s->name, -a->offset);
   7.213+		snprint(str, sizeof str, "%s-%ld(SP)", s->name, -a->offset);
   7.214 		break;
   7.215 
   7.216 	case D_PARAM:
   7.217-		sprint(str, "%s+%ld(FP)", s->name, a->offset);
   7.218+		snprint(str, sizeof str, "%s+%ld(FP)", s->name, a->offset);
   7.219 		break;
   7.220 	}
   7.221 out:
     8.1--- a/sys/src/cmd/5l/list.c
     8.2+++ b/sys/src/cmd/5l/list.c
     8.3@@ -21,7 +21,7 @@ prasm(Prog *p)
     8.4 int
     8.5 Pconv(Fmt *fp)
     8.6 {
     8.7-	char str[STRINGSZ], *s;
     8.8+	char str[STRINGSZ];
     8.9 	Prog *p;
    8.10 	int a;
    8.11 
    8.12@@ -30,30 +30,28 @@ Pconv(Fmt *fp)
    8.13 	a = p->as;
    8.14 	switch(a) {
    8.15 	default:
    8.16-		s = str;
    8.17-		s += sprint(s, "(%ld)", p->line);
    8.18 		if(p->reg == NREG)
    8.19-			sprint(s, "	%A%C	%D,%D",
    8.20-				a, p->scond, &p->from, &p->to);
    8.21+			snprint(str, sizeof str, "(%ld)	%A%C	%D,%D",
    8.22+				p->line, a, p->scond, &p->from, &p->to);
    8.23 		else
    8.24 		if(p->from.type != D_FREG)
    8.25-			sprint(s, "	%A%C	%D,R%d,%D",
    8.26-				a, p->scond, &p->from, p->reg, &p->to);
    8.27+			snprint(str, sizeof str, "(%ld)	%A%C	%D,R%d,%D",
    8.28+				p->line, a, p->scond, &p->from, p->reg, &p->to);
    8.29 		else
    8.30-			sprint(s, "	%A%C	%D,F%d,%D",
    8.31-				a, p->scond, &p->from, p->reg, &p->to);
    8.32+			snprint(str, sizeof str, "(%ld)	%A%C	%D,F%d,%D",
    8.33+				p->line, a, p->scond, &p->from, p->reg, &p->to);
    8.34 		break;
    8.35 
    8.36 	case ASWPW:
    8.37 	case ASWPBU:
    8.38-		sprint(str, "(%ld)	%A%C	R%d,%D,%D",
    8.39+		snprint(str, sizeof str, "(%ld)	%A%C	R%d,%D,%D",
    8.40 			p->line, a, p->scond, p->reg, &p->from, &p->to);
    8.41 		break;
    8.42 
    8.43 	case ADATA:
    8.44 	case AINIT:
    8.45 	case ADYNT:
    8.46-		sprint(str, "(%ld)	%A%C	%D/%d,%D",
    8.47+		snprint(str, sizeof str, "(%ld)	%A%C	%D/%d,%D",
    8.48 			p->line, a, p->scond, &p->from, p->reg, &p->to);
    8.49 		break;
    8.50 	}
    8.51@@ -124,94 +122,94 @@ Dconv(Fmt *fp)
    8.52 	switch(a->type) {
    8.53 
    8.54 	default:
    8.55-		sprint(str, "GOK-type(%d)", a->type);
    8.56+		snprint(str, sizeof str, "GOK-type(%d)", a->type);
    8.57 		break;
    8.58 
    8.59 	case D_NONE:
    8.60 		str[0] = 0;
    8.61 		if(a->name != D_NONE || a->reg != NREG || a->sym != S)
    8.62-			sprint(str, "%N(R%d)(NONE)", a, a->reg);
    8.63+			snprint(str, sizeof str, "%N(R%d)(NONE)", a, a->reg);
    8.64 		break;
    8.65 
    8.66 	case D_CONST:
    8.67 		if(a->reg == NREG)
    8.68-			sprint(str, "$%N", a);
    8.69+			snprint(str, sizeof str, "$%N", a);
    8.70 		else
    8.71-			sprint(str, "$%N(R%d)", a, a->reg);
    8.72+			snprint(str, sizeof str, "$%N(R%d)", a, a->reg);
    8.73 		break;
    8.74 
    8.75 	case D_SHIFT:
    8.76 		v = a->offset;
    8.77 		op = "<<>>->@>" + (((v>>5) & 3) << 1);
    8.78 		if(v & (1<<4))
    8.79-			sprint(str, "R%ld%c%cR%ld", v&15, op[0], op[1], (v>>8)&15);
    8.80+			snprint(str, sizeof str, "R%ld%c%cR%ld", v&15, op[0], op[1], (v>>8)&15);
    8.81 		else
    8.82-			sprint(str, "R%ld%c%c%ld", v&15, op[0], op[1], (v>>7)&31);
    8.83+			snprint(str, sizeof str, "R%ld%c%c%ld", v&15, op[0], op[1], (v>>7)&31);
    8.84 		if(a->reg != NREG)
    8.85-			sprint(str+strlen(str), "(R%d)", a->reg);
    8.86+			snprint(str+strlen(str), sizeof(str)-strlen(str), "(R%d)", a->reg);
    8.87 		break;
    8.88 
    8.89 	case D_OCONST:
    8.90-		sprint(str, "$*$%N", a);
    8.91+		snprint(str, sizeof str, "$*$%N", a);
    8.92 		if(a->reg != NREG)
    8.93-			sprint(str, "%N(R%d)(CONST)", a, a->reg);
    8.94+			snprint(str, sizeof str, "%N(R%d)(CONST)", a, a->reg);
    8.95 		break;
    8.96 
    8.97 	case D_OREG:
    8.98 		if(a->reg != NREG)
    8.99-			sprint(str, "%N(R%d)", a, a->reg);
   8.100+			snprint(str, sizeof str, "%N(R%d)", a, a->reg);
   8.101 		else
   8.102-			sprint(str, "%N", a);
   8.103+			snprint(str, sizeof str, "%N", a);
   8.104 		break;
   8.105 
   8.106 	case D_REG:
   8.107-		sprint(str, "R%d", a->reg);
   8.108+		snprint(str, sizeof str, "R%d", a->reg);
   8.109 		if(a->name != D_NONE || a->sym != S)
   8.110-			sprint(str, "%N(R%d)(REG)", a, a->reg);
   8.111+			snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
   8.112 		break;
   8.113 
   8.114 	case D_REGREG:
   8.115-		sprint(str, "(R%d,R%d)", a->reg, (int)a->offset);
   8.116+		snprint(str, sizeof str, "(R%d,R%d)", a->reg, (int)a->offset);
   8.117 		if(a->name != D_NONE || a->sym != S)
   8.118-			sprint(str, "%N(R%d)(REG)", a, a->reg);
   8.119+			snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
   8.120 		break;
   8.121 
   8.122 	case D_FREG:
   8.123-		sprint(str, "F%d", a->reg);
   8.124+		snprint(str, sizeof str, "F%d", a->reg);
   8.125 		if(a->name != D_NONE || a->sym != S)
   8.126-			sprint(str, "%N(R%d)(REG)", a, a->reg);
   8.127+			snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
   8.128 		break;
   8.129 
   8.130 	case D_PSR:
   8.131 		switch(a->reg) {
   8.132 		case 0:
   8.133-			sprint(str, "CPSR");
   8.134+			snprint(str, sizeof str, "CPSR");
   8.135 			break;
   8.136 		case 1:
   8.137-			sprint(str, "SPSR");
   8.138+			snprint(str, sizeof str, "SPSR");
   8.139 			break;
   8.140 		default:
   8.141-			sprint(str, "PSR%d", a->reg);
   8.142+			snprint(str, sizeof str, "PSR%d", a->reg);
   8.143 			break;
   8.144 		}
   8.145 		if(a->name != D_NONE || a->sym != S)
   8.146-			sprint(str, "%N(PSR%d)(REG)", a, a->reg);
   8.147+			snprint(str, sizeof str, "%N(PSR%d)(REG)", a, a->reg);
   8.148 		break;
   8.149 
   8.150 	case D_FPCR:
   8.151 		switch(a->reg){
   8.152 		case 0:
   8.153-			sprint(str, "FPSR");
   8.154+			snprint(str, sizeof str, "FPSR");
   8.155 			break;
   8.156 		case 1:
   8.157-			sprint(str, "FPCR");
   8.158+			snprint(str, sizeof str, "FPCR");
   8.159 			break;
   8.160 		default:
   8.161-			sprint(str, "FCR%d", a->reg);
   8.162+			snprint(str, sizeof str, "FCR%d", a->reg);
   8.163 			break;
   8.164 		}
   8.165 		if(a->name != D_NONE || a->sym != S)
   8.166-			sprint(str, "%N(FCR%d)(REG)", a, a->reg);
   8.167+			snprint(str, sizeof str, "%N(FCR%d)(REG)", a, a->reg);
   8.168 
   8.169 		break;
   8.170 
   8.171@@ -219,22 +217,22 @@ Dconv(Fmt *fp)
   8.172 		if(curp->cond != P) {
   8.173 			v = curp->cond->pc;
   8.174 			if(a->sym != S)
   8.175-				sprint(str, "%s+%.5lux(BRANCH)", a->sym->name, v);
   8.176+				snprint(str, sizeof str, "%s+%.5lux(BRANCH)", a->sym->name, v);
   8.177 			else
   8.178-				sprint(str, "%.5lux(BRANCH)", v);
   8.179+				snprint(str, sizeof str, "%.5lux(BRANCH)", v);
   8.180 		} else
   8.181 			if(a->sym != S)
   8.182-				sprint(str, "%s+%ld(APC)", a->sym->name, a->offset);
   8.183+				snprint(str, sizeof str, "%s+%ld(APC)", a->sym->name, a->offset);
   8.184 			else
   8.185-				sprint(str, "%ld(APC)", a->offset);
   8.186+				snprint(str, sizeof str, "%ld(APC)", a->offset);
   8.187 		break;
   8.188 
   8.189 	case D_FCONST:
   8.190-		sprint(str, "$%e", ieeedtod(a->ieee));
   8.191+		snprint(str, sizeof str, "$%e", ieeedtod(a->ieee));
   8.192 		break;
   8.193 
   8.194 	case D_SCONST:
   8.195-		sprint(str, "$\"%S\"", a->sval);
   8.196+		snprint(str, sizeof str, "$\"%S\"", a->sval);
   8.197 		break;
   8.198 	}
   8.199 	return fmtstrcpy(fp, str);
   8.200@@ -251,39 +249,39 @@ Nconv(Fmt *fp)
   8.201 	s = a->sym;
   8.202 	switch(a->name) {
   8.203 	default:
   8.204-		sprint(str, "GOK-name(%d)", a->name);
   8.205+		snprint(str, sizeof str, "GOK-name(%d)", a->name);
   8.206 		break;
   8.207 
   8.208 	case D_NONE:
   8.209-		sprint(str, "%ld", a->offset);
   8.210+		snprint(str, sizeof str, "%ld", a->offset);
   8.211 		break;
   8.212 
   8.213 	case D_EXTERN:
   8.214 		if(s == S)
   8.215-			sprint(str, "%ld(SB)", a->offset);
   8.216+			snprint(str, sizeof str, "%ld(SB)", a->offset);
   8.217 		else
   8.218-			sprint(str, "%s+%ld(SB)", s->name, a->offset);
   8.219+			snprint(str, sizeof str, "%s+%ld(SB)", s->name, a->offset);
   8.220 		break;
   8.221 
   8.222 	case D_STATIC:
   8.223 		if(s == S)
   8.224-			sprint(str, "<>+%ld(SB)", a->offset);
   8.225+			snprint(str, sizeof str, "<>+%ld(SB)", a->offset);
   8.226 		else
   8.227-			sprint(str, "%s<>+%ld(SB)", s->name, a->offset);
   8.228+			snprint(str, sizeof str, "%s<>+%ld(SB)", s->name, a->offset);
   8.229 		break;
   8.230 
   8.231 	case D_AUTO:
   8.232 		if(s == S)
   8.233-			sprint(str, "%ld(SP)", a->offset);
   8.234+			snprint(str, sizeof str, "%ld(SP)", a->offset);
   8.235 		else
   8.236-			sprint(str, "%s-%ld(SP)", s->name, -a->offset);
   8.237+			snprint(str, sizeof str, "%s-%ld(SP)", s->name, -a->offset);
   8.238 		break;
   8.239 
   8.240 	case D_PARAM:
   8.241 		if(s == S)
   8.242-			sprint(str, "%ld(FP)", a->offset);
   8.243+			snprint(str, sizeof str, "%ld(FP)", a->offset);
   8.244 		else
   8.245-			sprint(str, "%s+%ld(FP)", s->name, a->offset);
   8.246+			snprint(str, sizeof str, "%s+%ld(FP)", s->name, a->offset);
   8.247 		break;
   8.248 	}
   8.249 	return fmtstrcpy(fp, str);
     9.1--- a/sys/src/cmd/5l/obj.c
     9.2+++ b/sys/src/cmd/5l/obj.c
     9.3@@ -335,11 +335,9 @@ objfile(char *file)
     9.4 
     9.5 	if(file[0] == '-' && file[1] == 'l') {
     9.6 		if(debug['9'])
     9.7-			sprint(name, "/%s/lib/lib", thestring);
     9.8+			snprint(name, sizeof name, "/%s/lib/lib%s.a", thestring, file+2);
     9.9 		else
    9.10-			sprint(name, "/usr/%clib/lib", thechar);
    9.11-		strcat(name, file+2);
    9.12-		strcat(name, ".a");
    9.13+			snprint(name, sizeof name, "/usr/%clib/lib%s.a", thechar, file+2);
    9.14 		file = name;
    9.15 	}
    9.16 	if(debug['v'])
    9.17@@ -399,7 +397,7 @@ objfile(char *file)
    9.18 			s = lookup(e+5, 0);
    9.19 			if(s->type != SXREF)
    9.20 				continue;
    9.21-			sprint(pname, "%s(%s)", file, s->name);
    9.22+			snprint(pname, sizeof pname, "%s(%s)", file, s->name);
    9.23 			if(debug['v'])
    9.24 				Bprint(&bso, "%5.2f library: %s\n", cputime(), pname);
    9.25 			Bflush(&bso);
    9.26@@ -550,17 +548,17 @@ addlib(char *obj)
    9.27 		return;
    9.28 
    9.29 	if(histfrog[0]->name[1] == '/') {
    9.30-		sprint(name, "");
    9.31+		name[0] = 0;
    9.32 		i = 1;
    9.33 	} else
    9.34 	if(histfrog[0]->name[1] == '.') {
    9.35-		sprint(name, ".");
    9.36+		snprint(name, sizeof name, ".");
    9.37 		i = 0;
    9.38 	} else {
    9.39 		if(debug['9'])
    9.40-			sprint(name, "/%s/lib", thestring);
    9.41+			snprint(name, sizeof name, "/%s/lib", thestring);
    9.42 		else
    9.43-			sprint(name, "/usr/%clib", thechar);
    9.44+			snprint(name, sizeof name, "/usr/%clib", thechar);
    9.45 		i = 0;
    9.46 	}
    9.47 
    9.48@@ -1009,7 +1007,7 @@ loop:
    9.49 
    9.50 		if(p->from.type == D_FCONST && chipfloat(p->from.ieee) < 0) {
    9.51 			/* size sb 9 max */
    9.52-			sprint(literal, "$%lux", ieeedtof(p->from.ieee));
    9.53+			snprint(literal, sizeof literal, "$%lux", ieeedtof(p->from.ieee));
    9.54 			s = lookup(literal, 0);
    9.55 			if(s->type == 0) {
    9.56 				s->type = SBSS;
    9.57@@ -1038,7 +1036,7 @@ loop:
    9.58 
    9.59 		if(p->from.type == D_FCONST && chipfloat(p->from.ieee) < 0) {
    9.60 			/* size sb 18 max */
    9.61-			sprint(literal, "$%lux.%lux",
    9.62+			snprint(literal, sizeof literal, "$%lux.%lux",
    9.63 				p->from.ieee->l, p->from.ieee->h);
    9.64 			s = lookup(literal, 0);
    9.65 			if(s->type == 0) {
    10.1--- a/sys/src/cmd/6c/list.c
    10.2+++ b/sys/src/cmd/6c/list.c
    10.3@@ -20,20 +20,17 @@ Bconv(Fmt *fp)
    10.4 	Bits bits;
    10.5 	int i;
    10.6 
    10.7-	str[0] = 0;
    10.8 	bits = va_arg(fp->args, Bits);
    10.9 	while(bany(&bits)) {
   10.10 		i = bnum(bits);
   10.11 		if(str[0])
   10.12-			strcat(str, " ");
   10.13+			strncat(str, " ", sizeof str - 1);
   10.14 		if(var[i].sym == S) {
   10.15-			sprint(ss, "$%lld", var[i].offset);
   10.16+			snprint(ss, sizeof ss, "$%lld", var[i].offset);
   10.17 			s = ss;
   10.18 		} else
   10.19 			s = var[i].sym->name;
   10.20-		if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
   10.21-			break;
   10.22-		strcat(str, s);
   10.23+		strncat(str, s, sizeof str - 1);
   10.24 		bits.b[i/32] &= ~(1L << (i%32));
   10.25 	}
   10.26 	return fmtstrcpy(fp, str);
   10.27@@ -47,13 +44,13 @@ Pconv(Fmt *fp)
   10.28 
   10.29 	p = va_arg(fp->args, Prog*);
   10.30 	if(p->as == ADATA)
   10.31-		sprint(str, "	%A	%D/%d,%D",
   10.32+		snprint(str, sizeof str, "	%A	%D/%d,%D",
   10.33 			p->as, &p->from, p->from.scale, &p->to);
   10.34 	else if(p->as == ATEXT)
   10.35-		sprint(str, "	%A	%D,%d,%D",
   10.36+		snprint(str, sizeof str, "	%A	%D,%d,%D",
   10.37 			p->as, &p->from, p->from.scale, &p->to);
   10.38 	else
   10.39-		sprint(str, "	%A	%D,%D",
   10.40+		snprint(str, sizeof str, "	%A	%D,%D",
   10.41 			p->as, &p->from, &p->to);
   10.42 	return fmtstrcpy(fp, str);
   10.43 }
   10.44@@ -70,7 +67,7 @@ Aconv(Fmt *fp)
   10.45 int
   10.46 Dconv(Fmt *fp)
   10.47 {
   10.48-	char str[40], s[20];
   10.49+	char str[40];
   10.50 	Adr *a;
   10.51 	int i;
   10.52 
   10.53@@ -78,18 +75,18 @@ Dconv(Fmt *fp)
   10.54 	i = a->type;
   10.55 	if(i >= D_INDIR) {
   10.56 		if(a->offset)
   10.57-			sprint(str, "%lld(%R)", a->offset, i-D_INDIR);
   10.58+			snprint(str, sizeof str, "%lld(%R)", a->offset, i-D_INDIR);
   10.59 		else
   10.60-			sprint(str, "(%R)", i-D_INDIR);
   10.61+			snprint(str, sizeof str, "(%R)", i-D_INDIR);
   10.62 		goto brk;
   10.63 	}
   10.64 	switch(i) {
   10.65 
   10.66 	default:
   10.67 		if(a->offset)
   10.68-			sprint(str, "$%lld,%R", a->offset, i);
   10.69+			snprint(str, sizeof str, "$%lld,%R", a->offset, i);
   10.70 		else
   10.71-			sprint(str, "%R", i);
   10.72+			snprint(str, sizeof str, "%R", i);
   10.73 		break;
   10.74 
   10.75 	case D_NONE:
   10.76@@ -97,54 +94,51 @@ Dconv(Fmt *fp)
   10.77 		break;
   10.78 
   10.79 	case D_BRANCH:
   10.80-		sprint(str, "%lld(PC)", a->offset-pc);
   10.81+		snprint(str, sizeof str, "%lld(PC)", a->offset-pc);
   10.82 		break;
   10.83 
   10.84 	case D_EXTERN:
   10.85-		sprint(str, "%s+%lld(SB)", a->sym->name, a->offset);
   10.86+		snprint(str, sizeof str, "%s+%lld(SB)", a->sym->name, a->offset);
   10.87 		break;
   10.88 
   10.89 	case D_STATIC:
   10.90-		sprint(str, "%s<>+%lld(SB)", a->sym->name,
   10.91-			a->offset);
   10.92+		snprint(str, sizeof str, "%s<>+%lld(SB)", a->sym->name, a->offset);
   10.93 		break;
   10.94 
   10.95 	case D_AUTO:
   10.96-		sprint(str, "%s+%lld(SP)", a->sym->name, a->offset);
   10.97+		snprint(str, sizeof str, "%s+%lld(SP)", a->sym->name, a->offset);
   10.98 		break;
   10.99 
  10.100 	case D_PARAM:
  10.101 		if(a->sym)
  10.102-			sprint(str, "%s+%lld(FP)", a->sym->name, a->offset);
  10.103+			snprint(str, sizeof str, "%s+%lld(FP)", a->sym->name, a->offset);
  10.104 		else
  10.105-			sprint(str, "%lld(FP)", a->offset);
  10.106+			snprint(str, sizeof str, "%lld(FP)", a->offset);
  10.107 		break;
  10.108 
  10.109 	case D_CONST:
  10.110-		sprint(str, "$%lld", a->offset);
  10.111+		snprint(str, sizeof str, "$%lld", a->offset);
  10.112 		break;
  10.113 
  10.114 	case D_FCONST:
  10.115-		sprint(str, "$(%.17e)", a->dval);
  10.116+		snprint(str, sizeof str, "$(%.17e)", a->dval);
  10.117 		break;
  10.118 
  10.119 	case D_SCONST:
  10.120-		sprint(str, "$\"%S\"", a->sval);
  10.121+		snprint(str, sizeof str, "$\"%S\"", a->sval);
  10.122 		break;
  10.123 
  10.124 	case D_ADDR:
  10.125 		a->type = a->index;
  10.126 		a->index = D_NONE;
  10.127-		sprint(str, "$%D", a);
  10.128+		snprint(str, sizeof str, "$%D", a);
  10.129 		a->index = a->type;
  10.130 		a->type = D_ADDR;
  10.131 		goto conv;
  10.132 	}
  10.133 brk:
  10.134-	if(a->index != D_NONE) {
  10.135-		sprint(s, "(%R*%d)", (int)a->index, (int)a->scale);
  10.136-		strcat(str, s);
  10.137-	}
  10.138+	if(a->index != D_NONE) 
  10.139+		return fmtprint(fp, "%s(%R*%d)", str, (int)a->index, (int)a->scale);
  10.140 conv:
  10.141 	return fmtstrcpy(fp, str);
  10.142 }
  10.143@@ -284,9 +278,9 @@ Rconv(Fmt *fp)
  10.144 
  10.145 	r = va_arg(fp->args, int);
  10.146 	if(r >= D_AL && r <= D_NONE)
  10.147-		sprint(str, "%s", regstr[r-D_AL]);
  10.148+		snprint(str, sizeof str, "%s", regstr[r-D_AL]);
  10.149 	else
  10.150-		sprint(str, "gok(%d)", r);
  10.151+		snprint(str, sizeof str, "gok(%d)", r);
  10.152 
  10.153 	return fmtstrcpy(fp, str);
  10.154 }
    11.1--- a/sys/src/cmd/6l/list.c
    11.2+++ b/sys/src/cmd/6l/list.c
    11.3@@ -24,18 +24,18 @@ Pconv(Fmt *fp)
    11.4 	switch(p->as) {
    11.5 	case ATEXT:
    11.6 		if(p->from.scale) {
    11.7-			sprint(str, "(%ld)	%A	%D,%d,%D",
    11.8+			snprint(str, sizeof str, "(%ld)	%A	%D,%d,%D",
    11.9 				p->line, p->as, &p->from, p->from.scale, &p->to);
   11.10 			break;
   11.11 		}
   11.12 	default:
   11.13-		sprint(str, "(%ld)	%A	%D,%D",
   11.14+		snprint(str, sizeof str, "(%ld)	%A	%D,%D",
   11.15 			p->line, p->as, &p->from, &p->to);
   11.16 		break;
   11.17 	case ADATA:
   11.18 	case AINIT:
   11.19 	case ADYNT:
   11.20-		sprint(str, "(%ld)	%A	%D/%d,%D",
   11.21+		snprint(str, sizeof str, "(%ld)	%A	%D/%d,%D",
   11.22 			p->line, p->as, &p->from, p->from.scale, &p->to);
   11.23 		break;
   11.24 	}
   11.25@@ -55,7 +55,7 @@ Aconv(Fmt *fp)
   11.26 int
   11.27 Dconv(Fmt *fp)
   11.28 {
   11.29-	char str[40], s[20];
   11.30+	char str[40];
   11.31 	Adr *a;
   11.32 	int i;
   11.33 
   11.34@@ -63,18 +63,18 @@ Dconv(Fmt *fp)
   11.35 	i = a->type;
   11.36 	if(i >= D_INDIR) {
   11.37 		if(a->offset)
   11.38-			sprint(str, "%lld(%R)", a->offset, i-D_INDIR);
   11.39+			snprint(str, sizeof str, "%lld(%R)", a->offset, i-D_INDIR);
   11.40 		else
   11.41-			sprint(str, "(%R)", i-D_INDIR);
   11.42+			snprint(str, sizeof str, "(%R)", i-D_INDIR);
   11.43 		goto brk;
   11.44 	}
   11.45 	switch(i) {
   11.46 
   11.47 	default:
   11.48 		if(a->offset)
   11.49-			sprint(str, "$%lld,%R", a->offset, i);
   11.50+			snprint(str, sizeof str, "$%lld,%R", a->offset, i);
   11.51 		else
   11.52-			sprint(str, "%R", i);
   11.53+			snprint(str, sizeof str, "%R", i);
   11.54 		break;
   11.55 
   11.56 	case D_NONE:
   11.57@@ -84,59 +84,57 @@ Dconv(Fmt *fp)
   11.58 	case D_BRANCH:
   11.59 		if(bigP != P && bigP->pcond != P)
   11.60 			if(a->sym != S)
   11.61-				sprint(str, "%llux+%s", bigP->pcond->pc,
   11.62+				snprint(str, sizeof str, "%llux+%s", bigP->pcond->pc,
   11.63 					a->sym->name);
   11.64 			else
   11.65-				sprint(str, "%llux", bigP->pcond->pc);
   11.66+				snprint(str, sizeof str, "%llux", bigP->pcond->pc);
   11.67 		else
   11.68-			sprint(str, "%lld(PC)", a->offset);
   11.69+			snprint(str, sizeof str, "%lld(PC)", a->offset);
   11.70 		break;
   11.71 
   11.72 	case D_EXTERN:
   11.73-		sprint(str, "%s+%lld(SB)", a->sym->name, a->offset);
   11.74+		snprint(str, sizeof str, "%s+%lld(SB)", a->sym->name, a->offset);
   11.75 		break;
   11.76 
   11.77 	case D_STATIC:
   11.78-		sprint(str, "%s<%d>+%lld(SB)", a->sym->name,
   11.79+		snprint(str, sizeof str, "%s<%d>+%lld(SB)", a->sym->name,
   11.80 			a->sym->version, a->offset);
   11.81 		break;
   11.82 
   11.83 	case D_AUTO:
   11.84-		sprint(str, "%s+%lld(SP)", a->sym->name, a->offset);
   11.85+		snprint(str, sizeof str, "%s+%lld(SP)", a->sym->name, a->offset);
   11.86 		break;
   11.87 
   11.88 	case D_PARAM:
   11.89 		if(a->sym)
   11.90-			sprint(str, "%s+%lld(%s)", a->sym->name, a->offset, paramspace);
   11.91+			snprint(str, sizeof str, "%s+%lld(%s)", a->sym->name, a->offset, paramspace);
   11.92 		else
   11.93-			sprint(str, "%lld(%s)", a->offset, paramspace);
   11.94+			snprint(str, sizeof str, "%lld(%s)", a->offset, paramspace);
   11.95 		break;
   11.96 
   11.97 	case D_CONST:
   11.98-		sprint(str, "$%lld", a->offset);
   11.99+		snprint(str, sizeof str, "$%lld", a->offset);
  11.100 		break;
  11.101 
  11.102 	case D_FCONST:
  11.103-		sprint(str, "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l);
  11.104+		snprint(str, sizeof str, "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l);
  11.105 		break;
  11.106 
  11.107 	case D_SCONST:
  11.108-		sprint(str, "$\"%S\"", a->scon);
  11.109+		snprint(str, sizeof str, "$\"%S\"", a->scon);
  11.110 		break;
  11.111 
  11.112 	case D_ADDR:
  11.113 		a->type = a->index;
  11.114 		a->index = D_NONE;
  11.115-		sprint(str, "$%D", a);
  11.116+		snprint(str, sizeof str, "$%D", a);
  11.117 		a->index = a->type;
  11.118 		a->type = D_ADDR;
  11.119 		goto conv;
  11.120 	}
  11.121 brk:
  11.122-	if(a->index != D_NONE) {
  11.123-		sprint(s, "(%R*%d)", a->index, a->scale);
  11.124-		strcat(str, s);
  11.125-	}
  11.126+	if(a->index != D_NONE)
  11.127+		return fmtprint(fp, "%s(%R*%d)", str, a->index, a->scale);
  11.128 conv:
  11.129 	return fmtstrcpy(fp, str);
  11.130 }
  11.131@@ -276,9 +274,9 @@ Rconv(Fmt *fp)
  11.132 
  11.133 	r = va_arg(fp->args, int);
  11.134 	if(r >= D_AL && r <= D_NONE)
  11.135-		sprint(str, "%s", regstr[r-D_AL]);
  11.136+		snprint(str, sizeof str, "%s", regstr[r-D_AL]);
  11.137 	else
  11.138-		sprint(str, "gok(%d)", r);
  11.139+		snprint(str, sizeof str, "gok(%d)", r);
  11.140 
  11.141 	return fmtstrcpy(fp, str);
  11.142 }
    12.1--- a/sys/src/cmd/6l/obj.c
    12.2+++ b/sys/src/cmd/6l/obj.c
    12.3@@ -396,11 +396,9 @@ objfile(char *file)
    12.4 
    12.5 	if(file[0] == '-' && file[1] == 'l') {
    12.6 		if(debug['9'])
    12.7-			sprint(name, "/%s/lib/lib", thestring);
    12.8+			snprint(name, sizeof name, "/%s/lib/lib%s.a", thestring, file+2);
    12.9 		else
   12.10-			sprint(name, "/usr/%clib/lib", thechar);
   12.11-		strcat(name, file+2);
   12.12-		strcat(name, ".a");
   12.13+			snprint(name, sizeof name, "/usr/%clib/lib%s.a", thechar, file+2);
   12.14 		file = name;
   12.15 	}
   12.16 	if(debug['v'])
   12.17@@ -458,7 +456,7 @@ objfile(char *file)
   12.18 			s = lookup(e+5, 0);
   12.19 			if(s->type != SXREF)
   12.20 				continue;
   12.21-			sprint(pname, "%s(%s)", file, s->name);
   12.22+			snprint(pname, sizeof pname, "%s(%s)", file, s->name);
   12.23 			if(debug['v'])
   12.24 				Bprint(&bso, "%5.2f library: %s\n", cputime(), pname);
   12.25 			Bflush(&bso);
   12.26@@ -586,17 +584,17 @@ addlib(char *obj)
   12.27 		return;
   12.28 
   12.29 	if(histfrog[0]->name[1] == '/') {
   12.30-		sprint(name, "");
   12.31+		name[0] = 0;
   12.32 		i = 1;
   12.33 	} else
   12.34 	if(histfrog[0]->name[1] == '.') {
   12.35-		sprint(name, ".");
   12.36+		snprint(name, sizeof name, ".");
   12.37 		i = 0;
   12.38 	} else {
   12.39 		if(debug['9'])
   12.40-			sprint(name, "/%s/lib", thestring);
   12.41+			snprint(name, sizeof name, "/%s/lib", thestring);
   12.42 		else
   12.43-			sprint(name, "/usr/%clib", thechar);
   12.44+			snprint(name, sizeof name, "/usr/%clib", thechar);
   12.45 		i = 0;
   12.46 	}
   12.47 
   12.48@@ -1036,7 +1034,7 @@ loop:
   12.49 			goto casdef;
   12.50 		if(p->from.type == D_FCONST) {
   12.51 			/* size sb 9 max */
   12.52-			sprint(literal, "$%lux", ieeedtof(&p->from.ieee));
   12.53+			snprint(literal, sizeof literal, "$%lux", ieeedtof(&p->from.ieee));
   12.54 			s = lookup(literal, 0);
   12.55 			if(s->type == 0) {
   12.56 				s->type = SBSS;
   12.57@@ -1081,7 +1079,7 @@ loop:
   12.58 			goto casdef;
   12.59 		if(p->from.type == D_FCONST) {
   12.60 			/* size sb 18 max */
   12.61-			sprint(literal, "$%lux.%lux",
   12.62+			snprint(literal, sizeof literal, "$%lux.%lux",
   12.63 				p->from.ieee.l, p->from.ieee.h);
   12.64 			s = lookup(literal, 0);
   12.65 			if(s->type == 0) {
    13.1--- a/sys/src/cmd/7c/list.c
    13.2+++ b/sys/src/cmd/7c/list.c
    13.3@@ -20,20 +20,18 @@ Bconv(Fmt *fp)
    13.4 	Bits bits;
    13.5 	int i;
    13.6 
    13.7-	str[0] = 0;
    13.8+	memset(str, 0, sizeof str);
    13.9 	bits = va_arg(fp->args, Bits);
   13.10 	while(bany(&bits)) {
   13.11 		i = bnum(bits);
   13.12 		if(str[0])
   13.13-			strcat(str, " ");
   13.14+			strncat(str, " ", sizeof str - 1);
   13.15 		if(var[i].sym == S) {
   13.16-			sprint(ss, "$%lld", var[i].offset);
   13.17+			snprint(ss, sizeof ss, "$%lld", var[i].offset);
   13.18 			s = ss;
   13.19 		} else
   13.20 			s = var[i].sym->name;
   13.21-		if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
   13.22-			break;
   13.23-		strcat(str, s);
   13.24+		strncat(str, s, sizeof str - 1);
   13.25 		bits.b[i/32] &= ~(1L << (i%32));
   13.26 	}
   13.27 	return fmtstrcpy(fp, str);
   13.28@@ -49,18 +47,18 @@ Pconv(Fmt *fp)
   13.29 	p = va_arg(fp->args, Prog*);
   13.30 	a = p->as;
   13.31 	if(a == ADATA)
   13.32-		sprint(str, "	%A	%D/%d,%D", a, &p->from, p->reg, &p->to);
   13.33+		snprint(str, sizeof str, "	%A	%D/%d,%D", a, &p->from, p->reg, &p->to);
   13.34 	else
   13.35 	if(p->as == ATEXT)
   13.36-		sprint(str, "	%A	%D,%d,%D", a, &p->from, p->reg, &p->to);
   13.37+		snprint(str, sizeof str, "	%A	%D,%d,%D", a, &p->from, p->reg, &p->to);
   13.38 	else
   13.39 	if(p->reg == NREG)
   13.40-		sprint(str, "	%A	%D,%D", a, &p->from, &p->to);
   13.41+		snprint(str, sizeof str, "	%A	%D,%D", a, &p->from, &p->to);
   13.42 	else
   13.43 	if(p->from.type != D_FREG)
   13.44-		sprint(str, "	%A	%D,R%d,%D", a, &p->from, p->reg, &p->to);
   13.45+		snprint(str, sizeof str, "	%A	%D,R%d,%D", a, &p->from, p->reg, &p->to);
   13.46 	else
   13.47-		sprint(str, "	%A	%D,F%d,%D", a, &p->from, p->reg, &p->to);
   13.48+		snprint(str, sizeof str, "	%A	%D,F%d,%D", a, &p->from, p->reg, &p->to);
   13.49 	return fmtstrcpy(fp, str);
   13.50 }
   13.51 
   13.52@@ -87,57 +85,57 @@ Dconv(Fmt *fp)
   13.53 	switch(a->type) {
   13.54 
   13.55 	default:
   13.56-		sprint(str, "GOK-type(%d)", a->type);
   13.57+		snprint(str, sizeof str, "GOK-type(%d)", a->type);
   13.58 		break;
   13.59 
   13.60 	case D_NONE:
   13.61 		str[0] = 0;
   13.62 		if(a->name != D_NONE || a->reg != NREG || a->sym != S)
   13.63-			sprint(str, "%N(R%d)(NONE)", a, a->reg);
   13.64+			snprint(str, sizeof str, "%N(R%d)(NONE)", a, a->reg);
   13.65 		break;
   13.66 
   13.67 	case D_CONST:
   13.68 		if(a->reg != NREG)
   13.69-			sprint(str, "$%N(R%d)", a, a->reg);
   13.70+			snprint(str, sizeof str, "$%N(R%d)", a, a->reg);
   13.71 		else
   13.72-			sprint(str, "$%N", a);
   13.73+			snprint(str, sizeof str, "$%N", a);
   13.74 		break;
   13.75 
   13.76 	case D_OREG:
   13.77 		if(a->reg != NREG)
   13.78-			sprint(str, "%N(R%d)", a, a->reg);
   13.79+			snprint(str, sizeof str, "%N(R%d)", a, a->reg);
   13.80 		else
   13.81-			sprint(str, "%N", a);
   13.82+			snprint(str, sizeof str, "%N", a);
   13.83 		break;
   13.84 
   13.85 	case D_REG:
   13.86-		sprint(str, "R%d", a->reg);
   13.87+		snprint(str, sizeof str, "R%d", a->reg);
   13.88 		if(a->name != D_NONE || a->sym != S)
   13.89-			sprint(str, "%N(R%d)(REG)", a, a->reg);
   13.90+			snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
   13.91 		break;
   13.92 
   13.93 	case D_FREG:
   13.94-		sprint(str, "F%d", a->reg);
   13.95+		snprint(str, sizeof str, "F%d", a->reg);
   13.96 		if(a->name != D_NONE || a->sym != S)
   13.97-			sprint(str, "%N(R%d)(REG)", a, a->reg);
   13.98+			snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
   13.99 		break;
  13.100 
  13.101 	case D_FCREG:
  13.102-		sprint(str, "FPCR");
  13.103+		snprint(str, sizeof str, "FPCR");
  13.104 		if(a->reg != 0 || a->name != D_NONE || a->sym != S)
  13.105-			sprint(str, "%N(FPCR%d)(REG)", a, a->reg);
  13.106+			snprint(str, sizeof str, "%N(FPCR%d)(REG)", a, a->reg);
  13.107 		break;
  13.108 
  13.109 	case D_BRANCH:
  13.110-		sprint(str, "%lld(PC)", a->offset-pc);
  13.111+		snprint(str, sizeof str, "%lld(PC)", a->offset-pc);
  13.112 		break;
  13.113 
  13.114 	case D_FCONST:
  13.115-		sprint(str, "$%.17e", a->dval);
  13.116+		snprint(str, sizeof str, "$%.17e", a->dval);
  13.117 		break;
  13.118 
  13.119 	case D_SCONST:
  13.120-		sprint(str, "$\"%S\"", a->sval);
  13.121+		snprint(str, sizeof str, "$\"%S\"", a->sval);
  13.122 		break;
  13.123 	}
  13.124 	return fmtstrcpy(fp, str);
  13.125@@ -200,32 +198,32 @@ Nconv(Fmt *fp)
  13.126 	a = va_arg(fp->args, Adr*);
  13.127 	s = a->sym;
  13.128 	if(s == S) {
  13.129-		sprint(str, "%lld", a->offset);
  13.130+		snprint(str, sizeof str, "%lld", a->offset);
  13.131 		goto out;
  13.132 	}
  13.133 	switch(a->name) {
  13.134 	default:
  13.135-		sprint(str, "GOK-name(%d)", a->name);
  13.136+		snprint(str, sizeof str, "GOK-name(%d)", a->name);
  13.137 		break;
  13.138 
  13.139 	case D_NONE:
  13.140-		sprint(str, "%lld", a->offset);
  13.141+		snprint(str, sizeof str, "%lld", a->offset);
  13.142 		break;
  13.143 
  13.144 	case D_EXTERN:
  13.145-		sprint(str, "%s+%lld(SB)", s->name, a->offset);
  13.146+		snprint(str, sizeof str, "%s+%lld(SB)", s->name, a->offset);
  13.147 		break;
  13.148 
  13.149 	case D_STATIC:
  13.150-		sprint(str, "%s<>+%lld(SB)", s->name, a->offset);
  13.151+		snprint(str, sizeof str, "%s<>+%lld(SB)", s->name, a->offset);
  13.152 		break;
  13.153 
  13.154 	case D_AUTO:
  13.155-		sprint(str, "%s-%lld(SP)", s->name, -a->offset);
  13.156+		snprint(str, sizeof str, "%s-%lld(SP)", s->name, -a->offset);
  13.157 		break;
  13.158 
  13.159 	case D_PARAM:
  13.160-		sprint(str, "%s+%lld(FP)", s->name, a->offset);
  13.161+		snprint(str, sizeof str, "%s+%lld(FP)", s->name, a->offset);
  13.162 		break;
  13.163 	}
  13.164 out:
    14.1--- a/sys/src/cmd/7l/list.c
    14.2+++ b/sys/src/cmd/7l/list.c
    14.3@@ -28,18 +28,18 @@ Pconv(Fmt *fp)
    14.4 	curp = p;
    14.5 	a = p->as;
    14.6 	if(a == ADATA)
    14.7-		sprint(str, "(%ld)	%A	%D/%d,%D",
    14.8+		snprint(str, sizeof str, "(%ld)	%A	%D/%d,%D",
    14.9 			p->line, a, &p->from, p->reg, &p->to);
   14.10 	else
   14.11 	if(p->reg == NREG)
   14.12-		sprint(str, "(%ld)	%A	%D,%D",
   14.13+		snprint(str, sizeof str, "(%ld)	%A	%D,%D",
   14.14 			p->line, a, &p->from, &p->to);
   14.15 	else
   14.16 	if(p->from.type != D_FREG)
   14.17-		sprint(str, "(%ld)	%A	%D,R%d,%D",
   14.18+		snprint(str, sizeof str, "(%ld)	%A	%D,R%d,%D",
   14.19 			p->line, a, &p->from, p->reg, &p->to);
   14.20 	else
   14.21-		sprint(str, "(%ld)	%A	%D,F%d,%D",
   14.22+		snprint(str, sizeof str, "(%ld)	%A	%D,F%d,%D",
   14.23 			p->line, a, &p->from, p->reg, &p->to);
   14.24 	return fmtstrcpy(fp, str);
   14.25 }
   14.26@@ -68,50 +68,50 @@ Dconv(Fmt *fp)
   14.27 	switch(a->type) {
   14.28 
   14.29 	default:
   14.30-		sprint(str, "GOK-type(%d)", a->type);
   14.31+		snprint(str, sizeof str, "GOK-type(%d)", a->type);
   14.32 		break;
   14.33 
   14.34 	case D_NONE:
   14.35 		str[0] = 0;
   14.36 		if(a->name != D_NONE || a->reg != NREG || a->sym != S)
   14.37-			sprint(str, "%N(R%d)(NONE)", a, a->reg);
   14.38+			snprint(str, sizeof str, "%N(R%d)(NONE)", a, a->reg);
   14.39 		break;
   14.40 
   14.41 	case D_CONST:
   14.42-		sprint(str, "$%N", a);
   14.43+		snprint(str, sizeof str, "$%N", a);
   14.44 		if(a->reg != NREG)
   14.45-			sprint(str, "%N(R%d)(CONST)", a, a->reg);
   14.46+			snprint(str, sizeof str, "%N(R%d)(CONST)", a, a->reg);
   14.47 		break;
   14.48 
   14.49 	case D_OREG:
   14.50 		if(a->reg != NREG)
   14.51-			sprint(str, "%N(R%d)", a, a->reg);
   14.52+			snprint(str, sizeof str, "%N(R%d)", a, a->reg);
   14.53 		else
   14.54-			sprint(str, "%N", a);
   14.55+			snprint(str, sizeof str, "%N", a);
   14.56 		break;
   14.57 
   14.58 	case D_REG:
   14.59-		sprint(str, "R%d", a->reg);
   14.60+		snprint(str, sizeof str, "R%d", a->reg);
   14.61 		if(a->name != D_NONE || a->sym != S)
   14.62-			sprint(str, "%N(R%d)(REG)", a, a->reg);
   14.63+			snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
   14.64 		break;
   14.65 
   14.66 	case D_PREG:
   14.67-		sprint(str, "P%d", a->reg & 255);
   14.68+		snprint(str, sizeof str, "P%d", a->reg & 255);
   14.69 		if(a->name != D_NONE || a->sym != S)
   14.70-			sprint(str, "%N(R%d)(PREG)", a, a->reg);
   14.71+			snprint(str, sizeof str, "%N(R%d)(PREG)", a, a->reg);
   14.72 		break;
   14.73 
   14.74 	case D_FREG:
   14.75-		sprint(str, "F%d", a->reg);
   14.76+		snprint(str, sizeof str, "F%d", a->reg);
   14.77 		if(a->name != D_NONE || a->sym != S)
   14.78-			sprint(str, "%N(R%d)(FREG)", a, a->reg);
   14.79+			snprint(str, sizeof str, "%N(R%d)(FREG)", a, a->reg);
   14.80 		break;
   14.81 
   14.82 	case D_FCREG:
   14.83-		sprint(str, "FPCR");
   14.84+		snprint(str, sizeof str, "FPCR");
   14.85 		if(a->name != D_NONE || a->sym != S)
   14.86-			sprint(str, "%N(R%d)(FCREG)", a, a->reg);
   14.87+			snprint(str, sizeof str, "%N(R%d)(FCREG)", a, a->reg);
   14.88 		break;
   14.89 
   14.90 	case D_BRANCH:	/* botch */
   14.91@@ -120,22 +120,22 @@ Dconv(Fmt *fp)
   14.92 			if(v >= INITTEXT)
   14.93 				v -= INITTEXT-HEADR;
   14.94 			if(a->sym != S)
   14.95-				sprint(str, "%s+%.5lux(BRANCH)", a->sym->name, v);
   14.96+				snprint(str, sizeof str, "%s+%.5lux(BRANCH)", a->sym->name, v);
   14.97 			else
   14.98-				sprint(str, "%.5lux(BRANCH)", v);
   14.99+				snprint(str, sizeof str, "%.5lux(BRANCH)", v);
  14.100 		} else
  14.101 			if(a->sym != S)
  14.102-				sprint(str, "%s+%lld(APC)", a->sym->name, a->offset);
  14.103+				snprint(str, sizeof str, "%s+%lld(APC)", a->sym->name, a->offset);
  14.104 			else
  14.105-				sprint(str, "%lld(APC)", a->offset);
  14.106+				snprint(str, sizeof str, "%lld(APC)", a->offset);
  14.107 		break;
  14.108 
  14.109 	case D_FCONST:
  14.110-		sprint(str, "$%e", ieeedtod(a->ieee));
  14.111+		snprint(str, sizeof str, "$%e", ieeedtod(a->ieee));
  14.112 		break;
  14.113 
  14.114 	case D_SCONST:
  14.115-		sprint(str, "$\"%S\"", a->sval);
  14.116+		snprint(str, sizeof str, "$\"%S\"", a->sval);
  14.117 		break;
  14.118 	}
  14.119 	return fmtstrcpy(fp, str);
  14.120@@ -151,32 +151,32 @@ Nconv(Fmt *fp)
  14.121 	a = va_arg(fp->args, Adr*);
  14.122 	s = a->sym;
  14.123 	if(s == S) {
  14.124-		sprint(str, "%lld", a->offset);
  14.125+		snprint(str, sizeof str, "%lld", a->offset);
  14.126 		goto out;
  14.127 	}
  14.128 	switch(a->name) {
  14.129 	default:
  14.130-		sprint(str, "GOK-name(%d)", a->name);
  14.131+		snprint(str, sizeof str, "GOK-name(%d)", a->name);
  14.132 		break;
  14.133 
  14.134 	case D_NONE:
  14.135-		sprint(str, "%lld", a->offset);
  14.136+		snprint(str, sizeof str, "%lld", a->offset);
  14.137 		break;
  14.138 
  14.139 	case D_EXTERN:
  14.140-		sprint(str, "%s+%lld(SB)", s->name, a->offset);
  14.141+		snprint(str, sizeof str, "%s+%lld(SB)", s->name, a->offset);
  14.142 		break;
  14.143 
  14.144 	case D_STATIC:
  14.145-		sprint(str, "%s<>+%lld(SB)", s->name, a->offset);
  14.146+		snprint(str, sizeof str, "%s<>+%lld(SB)", s->name, a->offset);
  14.147 		break;
  14.148 
  14.149 	case D_AUTO:
  14.150-		sprint(str, "%s-%lld(SP)", s->name, -a->offset);
  14.151+		snprint(str, sizeof str, "%s-%lld(SP)", s->name, -a->offset);
  14.152 		break;
  14.153 
  14.154 	case D_PARAM:
  14.155-		sprint(str, "%s+%lld(FP)", s->name, a->offset);
  14.156+		snprint(str, sizeof str, "%s+%lld(FP)", s->name, a->offset);
  14.157 		break;
  14.158 	}
  14.159 out:
    15.1--- a/sys/src/cmd/7l/obj.c
    15.2+++ b/sys/src/cmd/7l/obj.c
    15.3@@ -253,11 +253,9 @@ objfile(char *file)
    15.4 
    15.5 	if(file[0] == '-' && file[1] == 'l') {
    15.6 		if(debug['9'])
    15.7-			sprint(name, "/%s/lib/lib", thestring);
    15.8+			snprint(name, sizeof name, "/%s/lib/lib%s.a", thestring, file+2);
    15.9 		else
   15.10-			sprint(name, "/usr/%clib/lib", thechar);
   15.11-		strcat(name, file+2);
   15.12-		strcat(name, ".a");
   15.13+			snprint(name, sizeof name, "/usr/%clib/lib%s.a", thechar, file+2);
   15.14 		file = name;
   15.15 	}
   15.16 	if(debug['v'])
   15.17@@ -317,7 +315,7 @@ objfile(char *file)
   15.18 			s = lookup(e+5, 0);
   15.19 			if(s->type != SXREF)
   15.20 				continue;
   15.21-			sprint(pname, "%s(%s)", file, s->name);
   15.22+			snprint(pname, sizeof pname, "%s(%s)", file, s->name);
   15.23 			if(debug['v'])
   15.24 				Bprint(&bso, "%5.2f library: %s\n", cputime(), pname);
   15.25 			Bflush(&bso);
   15.26@@ -464,17 +462,17 @@ addlib(char *obj)
   15.27 		return;
   15.28 
   15.29 	if(histfrog[0]->name[1] == '/') {
   15.30-		sprint(name, "");
   15.31+		name[0] = 0;
   15.32 		i = 1;
   15.33 	} else
   15.34 	if(histfrog[0]->name[1] == '.') {
   15.35-		sprint(name, ".");
   15.36+		snprint(name, sizeof name, ".");
   15.37 		i = 0;
   15.38 	} else {
   15.39 		if(debug['9'])
   15.40-			sprint(name, "/%s/lib", thestring);
   15.41+			snprint(name, sizeof name, "/%s/lib", thestring);
   15.42 		else
   15.43-			sprint(name, "/usr/%clib", thechar);
   15.44+			snprint(name, sizeof name, "/usr/%clib", thechar);
   15.45 		i = 0;
   15.46 	}
   15.47 
   15.48@@ -878,7 +876,7 @@ loop:
   15.49 
   15.50 		if(p->from.type == D_FCONST) {
   15.51 			/* size sb 9 max */
   15.52-			sprint(literal, "$%lux", ieeedtof(p->from.ieee));
   15.53+			snprint(literal, sizeof literal, "$%lux", ieeedtof(p->from.ieee));
   15.54 			s = lookup(literal, 0);
   15.55 			if(s->type == 0) {
   15.56 				s->type = SBSS;
   15.57@@ -907,7 +905,7 @@ loop:
   15.58 
   15.59 		if(p->from.type == D_FCONST) {
   15.60 			/* size sb 18 max */
   15.61-			sprint(literal, "$%lux.%lux",
   15.62+			snprint(literal, sizeof literal, "$%lux.%lux",
   15.63 				p->from.ieee->l, p->from.ieee->h);
   15.64 			s = lookup(literal, 0);
   15.65 			if(s->type == 0) {
    16.1--- a/sys/src/cmd/7l/pass.c
    16.2+++ b/sys/src/cmd/7l/pass.c
    16.3@@ -130,9 +130,9 @@ dodata(void)
    16.4 				continue;
    16.5 			/* size should be 19 max */
    16.6 			if(strlen(s->name) >= 10)	/* has loader address */ 
    16.7-				sprint(literal, "$%p.%llux", s, p->from.offset);
    16.8+				snprint(literal, sizeof literal, "$%p.%llux", s, p->from.offset);
    16.9 			else
   16.10-				sprint(literal, "$%s.%d.%llux", s->name, s->version, p->from.offset);
   16.11+				snprint(literal, sizeof literal, "$%s.%d.%llux", s->name, s->version, p->from.offset);
   16.12 		} else {
   16.13 			if(p->from.name != D_NONE)
   16.14 				continue;
   16.15@@ -147,7 +147,7 @@ dodata(void)
   16.16 			if (vv <= 0x7FFFFFFFLL && vv >= -0x80000000LL)
   16.17 				size = 4;
   16.18 			/* size should be 17 max */
   16.19-			sprint(literal, "$%llux", vv);
   16.20+			snprint(literal, sizeof literal, "$%llux", vv);
   16.21 		}
   16.22 		s = lookup(literal, 0);
   16.23 		if(s->type == 0) {
    17.1--- a/sys/src/cmd/8c/list.c
    17.2+++ b/sys/src/cmd/8c/list.c
    17.3@@ -20,20 +20,18 @@ Bconv(Fmt *fp)
    17.4 	Bits bits;
    17.5 	int i;
    17.6 
    17.7-	str[0] = 0;
    17.8+	memset(str, 0, sizeof str);
    17.9 	bits = va_arg(fp->args, Bits);
   17.10 	while(bany(&bits)) {
   17.11 		i = bnum(bits);
   17.12 		if(str[0])
   17.13-			strcat(str, " ");
   17.14+			strncat(str, " ", sizeof str - 1);
   17.15 		if(var[i].sym == S) {
   17.16 			snprint(ss, sizeof(ss), "$%ld", var[i].offset);
   17.17 			s = ss;
   17.18 		} else
   17.19 			s = var[i].sym->name;
   17.20-		if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
   17.21-			break;
   17.22-		strcat(str, s);
   17.23+		strncat(str, s, sizeof str - 1);
   17.24 		bits.b[i/32] &= ~(1L << (i%32));
   17.25 	}
   17.26 	return fmtstrcpy(fp, str);
   17.27@@ -70,7 +68,7 @@ Aconv(Fmt *fp)
   17.28 int
   17.29 Dconv(Fmt *fp)
   17.30 {
   17.31-	char str[40], s[20];
   17.32+	char str[40];
   17.33 	Adr *a;
   17.34 	int i;
   17.35 
   17.36@@ -105,8 +103,7 @@ Dconv(Fmt *fp)
   17.37 		break;
   17.38 
   17.39 	case D_STATIC:
   17.40-		snprint(str, sizeof(str), "%s<>+%ld(SB)", a->sym->name,
   17.41-			a->offset);
   17.42+		snprint(str, sizeof(str), "%s<>+%ld(SB)", a->sym->name, a->offset);
   17.43 		break;
   17.44 
   17.45 	case D_AUTO:
   17.46@@ -141,11 +138,8 @@ Dconv(Fmt *fp)
   17.47 		goto conv;
   17.48 	}
   17.49 brk:
   17.50-	if(a->index != D_NONE) {
   17.51-		fmtstrcpy(fp, str);
   17.52-		snprint(s, sizeof(s), "(%R*%d)", (int)a->index, (int)a->scale);
   17.53-		return fmtstrcpy(fp, s);
   17.54-	}
   17.55+	if(a->index != D_NONE)
   17.56+		return fmtprint(fp, "%s(%R*%d)", str, (int)a->index, (int)a->scale);
   17.57 conv:
   17.58 	return fmtstrcpy(fp, str);
   17.59 }
    18.1--- a/sys/src/cmd/8l/list.c
    18.2+++ b/sys/src/cmd/8l/list.c
    18.3@@ -55,7 +55,7 @@ Aconv(Fmt *fp)
    18.4 int
    18.5 Dconv(Fmt *fp)
    18.6 {
    18.7-	char str[STRINGSZ+40], s[20];
    18.8+	char str[STRINGSZ+40];
    18.9 	Adr *a;
   18.10 	int i;
   18.11 
   18.12@@ -130,10 +130,8 @@ Dconv(Fmt *fp)
   18.13 		goto conv;
   18.14 	}
   18.15 brk:
   18.16-	if(a->index != D_NONE) {
   18.17-		snprint(s, sizeof(s), "(%R*%d)", a->index, a->scale);
   18.18-		strcat(str, s);
   18.19-	}
   18.20+	if(a->index != D_NONE)
   18.21+		return fmtprint(fp, "%s(%R*%d)", str, a->index, a->scale);
   18.22 conv:
   18.23 	return fmtstrcpy(fp, str);
   18.24 }
    19.1--- a/sys/src/cmd/8l/obj.c
    19.2+++ b/sys/src/cmd/8l/obj.c
    19.3@@ -393,11 +393,9 @@ objfile(char *file)
    19.4 
    19.5 	if(file[0] == '-' && file[1] == 'l') {
    19.6 		if(debug['9'])
    19.7-			sprint(name, "/%s/lib/lib", thestring);
    19.8+			snprint(name, sizeof name, "/%s/lib/lib%s.a", thestring, file+2);
    19.9 		else
   19.10-			sprint(name, "/usr/%clib/lib", thechar);
   19.11-		strcat(name, file+2);
   19.12-		strcat(name, ".a");
   19.13+			snprint(name, sizeof name, "/usr/%clib/lib%s.a", thechar, file+2);
   19.14 		file = name;
   19.15 	}
   19.16 	if(debug['v'])
   19.17@@ -455,7 +453,7 @@ objfile(char *file)
   19.18 			s = lookup(e+5, 0);
   19.19 			if(s->type != SXREF)
   19.20 				continue;
   19.21-			sprint(pname, "%s(%s)", file, s->name);
   19.22+			snprint(pname, sizeof pname, "%s(%s)", file, s->name);
   19.23 			if(debug['v'])
   19.24 				Bprint(&bso, "%5.2f library: %s\n", cputime(), pname);
   19.25 			Bflush(&bso);
   19.26@@ -574,17 +572,17 @@ addlib(char *obj)
   19.27 		return;
   19.28 
   19.29 	if(histfrog[0]->name[1] == '/') {
   19.30-		sprint(name, "");
   19.31+		name[0] = 0;
   19.32 		i = 1;
   19.33 	} else
   19.34 	if(histfrog[0]->name[1] == '.') {
   19.35-		sprint(name, ".");
   19.36+		snprint(name, sizeof name, ".");
   19.37 		i = 0;
   19.38 	} else {
   19.39 		if(debug['9'])
   19.40-			sprint(name, "/%s/lib", thestring);
   19.41+			snprint(name, sizeof name, "/%s/lib", thestring);
   19.42 		else
   19.43-			sprint(name, "/usr/%clib", thechar);
   19.44+			snprint(name, sizeof name, "/usr/%clib", thechar);
   19.45 		i = 0;
   19.46 	}
   19.47 
   19.48@@ -1012,7 +1010,7 @@ loop:
   19.49 			goto casdef;
   19.50 		if(p->from.type == D_FCONST) {
   19.51 			/* size sb 9 max */
   19.52-			sprint(literal, "$%lux", ieeedtof(&p->from.ieee));
   19.53+			snprint(literal, sizeof literal, "$%lux", ieeedtof(&p->from.ieee));
   19.54 			s = lookup(literal, 0);
   19.55 			if(s->type == 0) {
   19.56 				s->type = SBSS;
   19.57@@ -1057,7 +1055,7 @@ loop:
   19.58 			goto casdef;
   19.59 		if(p->from.type == D_FCONST) {
   19.60 			/* size sb 18 max */
   19.61-			sprint(literal, "$%lux.%lux",
   19.62+			snprint(literal, sizeof literal, "$%lux.%lux",
   19.63 				p->from.ieee.l, p->from.ieee.h);
   19.64 			s = lookup(literal, 0);
   19.65 			if(s->type == 0) {
    20.1--- a/sys/src/cmd/kc/list.c
    20.2+++ b/sys/src/cmd/kc/list.c
    20.3@@ -20,20 +20,18 @@ Bconv(Fmt *fp)
    20.4 	Bits bits;
    20.5 	int i;
    20.6 
    20.7-	str[0] = 0;
    20.8+	memset(str, 0, sizeof str);
    20.9 	bits = va_arg(fp->args, Bits);
   20.10 	while(bany(&bits)) {
   20.11 		i = bnum(bits);
   20.12 		if(str[0])
   20.13-			strcat(str, " ");
   20.14+			strncat(str, " ", sizeof str - 1);
   20.15 		if(var[i].sym == S) {
   20.16-			sprint(ss, "$%ld", var[i].offset);
   20.17+			snprint(ss, sizeof ss, "$%ld", var[i].offset);
   20.18 			s = ss;
   20.19 		} else
   20.20 			s = var[i].sym->name;
   20.21-		if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
   20.22-			break;
   20.23-		strcat(str, s);
   20.24+		strncat(str, s, sizeof str - 1);
   20.25 		bits.b[i/32] &= ~(1L << (i%32));
   20.26 	}
   20.27 	return fmtstrcpy(fp, str);
   20.28@@ -49,18 +47,18 @@ Pconv(Fmt *fp)
   20.29 	p = va_arg(fp->args, Prog*);
   20.30 	a = p->as;
   20.31 	if(a == ADATA)
   20.32-		sprint(str, "	%A	%D/%d,%D", a, &p->from, p->reg, &p->to);
   20.33+		snprint(str, sizeof str, "	%A	%D/%d,%D", a, &p->from, p->reg, &p->to);
   20.34 	else
   20.35 	if(p->as == ATEXT)
   20.36-		sprint(str, "	%A	%D,%d,%D", a, &p->from, p->reg, &p->to);
   20.37+		snprint(str, sizeof str, "	%A	%D,%d,%D", a, &p->from, p->reg, &p->to);
   20.38 	else
   20.39 	if(p->reg == NREG)
   20.40-		sprint(str, "	%A	%D,%D", a, &p->from, &p->to);
   20.41+		snprint(str, sizeof str, "	%A	%D,%D", a, &p->from, &p->to);
   20.42 	else
   20.43 	if(p->from.type != D_FREG)
   20.44-		sprint(str, "	%A	%D,R%d,%D", a, &p->from, p->reg, &p->to);
   20.45+		snprint(str, sizeof str, "	%A	%D,R%d,%D", a, &p->from, p->reg, &p->to);
   20.46 	else
   20.47-		sprint(str, "	%A	%D,F%d,%D", a, &p->from, p->reg, &p->to);
   20.48+		snprint(str, sizeof str, "	%A	%D,F%d,%D", a, &p->from, p->reg, &p->to);
   20.49 	return fmtstrcpy(fp, str);
   20.50 }
   20.51 
   20.52@@ -87,57 +85,57 @@ Dconv(Fmt *fp)
   20.53 	switch(a->type) {
   20.54 
   20.55 	default:
   20.56-		sprint(str, "GOK-type(%d)", a->type);
   20.57+		snprint(str, sizeof str, "GOK-type(%d)", a->type);
   20.58 		break;
   20.59 
   20.60 	case D_NONE:
   20.61 		str[0] = 0;
   20.62 		if(a->name != D_NONE || a->reg != NREG || a->sym != S)
   20.63-			sprint(str, "%N(R%d)(NONE)", a, a->reg);
   20.64+			snprint(str, sizeof str, "%N(R%d)(NONE)", a, a->reg);
   20.65 		break;
   20.66 
   20.67 	case D_CONST:
   20.68 		if(a->reg != NREG)
   20.69-			sprint(str, "$%N(R%d)", a, a->reg);
   20.70+			snprint(str, sizeof str, "$%N(R%d)", a, a->reg);
   20.71 		else
   20.72-			sprint(str, "$%N", a);
   20.73+			snprint(str, sizeof str, "$%N", a);
   20.74 		break;
   20.75 
   20.76 	case D_OREG:
   20.77 		if(a->reg != NREG)
   20.78-			sprint(str, "%N(R%d)", a, a->reg);
   20.79+			snprint(str, sizeof str, "%N(R%d)", a, a->reg);
   20.80 		else
   20.81-			sprint(str, "%N", a);
   20.82+			snprint(str, sizeof str, "%N", a);
   20.83 		break;
   20.84 
   20.85 	case D_REG:
   20.86-		sprint(str, "R%d", a->reg);
   20.87+		snprint(str, sizeof str, "R%d", a->reg);
   20.88 		if(a->name != D_NONE || a->sym != S)
   20.89-			sprint(str, "%N(R%d)(REG)", a, a->reg);
   20.90+			snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
   20.91 		break;
   20.92 
   20.93 	case D_FREG:
   20.94-		sprint(str, "F%d", a->reg);
   20.95+		snprint(str, sizeof str, "F%d", a->reg);
   20.96 		if(a->name != D_NONE || a->sym != S)
   20.97-			sprint(str, "%N(F%d)(REG)", a, a->reg);
   20.98+			snprint(str, sizeof str, "%N(F%d)(REG)", a, a->reg);
   20.99 		break;
  20.100 
  20.101 	case D_CREG:
  20.102-		sprint(str, "C%d", a->reg);
  20.103+		snprint(str, sizeof str, "C%d", a->reg);
  20.104 		if(a->name != D_NONE || a->sym != S)
  20.105-			sprint(str, "%N(C%d)(REG)", a, a->reg);
  20.106+			snprint(str, sizeof str, "%N(C%d)(REG)", a, a->reg);
  20.107 		break;
  20.108 
  20.109 	case D_BRANCH:
  20.110-		sprint(str, "%ld(PC)", a->offset-pc);
  20.111+		snprint(str, sizeof str, "%ld(PC)", a->offset-pc);
  20.112 		break;
  20.113 
  20.114 	case D_FCONST:
  20.115-		sprint(str, "$%.17e", a->dval);
  20.116+		snprint(str, sizeof str, "$%.17e", a->dval);
  20.117 		break;
  20.118 
  20.119 	case D_SCONST:
  20.120-		sprint(str, "$\"%S\"", a->sval);
  20.121+		snprint(str, sizeof str, "$\"%S\"", a->sval);
  20.122 		break;
  20.123 	}
  20.124 	return fmtstrcpy(fp, str);
  20.125@@ -200,28 +198,28 @@ Nconv(Fmt *fp)
  20.126 	a = va_arg(fp->args, Adr*);
  20.127 	s = a->sym;
  20.128 	if(s == S) {
  20.129-		sprint(str, "%ld", a->offset);
  20.130+		snprint(str, sizeof str, "%ld", a->offset);
  20.131 		goto out;
  20.132 	}
  20.133 	switch(a->name) {
  20.134 	default:
  20.135-		sprint(str, "GOK-name(%d)", a->name);
  20.136+		snprint(str, sizeof str, "GOK-name(%d)", a->name);
  20.137 		break;
  20.138 
  20.139 	case D_EXTERN:
  20.140-		sprint(str, "%s+%ld(SB)", s->name, a->offset);
  20.141+		snprint(str, sizeof str, "%s+%ld(SB)", s->name, a->offset);
  20.142 		break;
  20.143 
  20.144 	case D_STATIC:
  20.145-		sprint(str, "%s<>+%ld(SB)", s->name, a->offset);
  20.146+		snprint(str, sizeof str, "%s<>+%ld(SB)", s->name, a->offset);
  20.147 		break;
  20.148 
  20.149 	case D_AUTO:
  20.150-		sprint(str, "%s-%ld(SP)", s->name, -a->offset);
  20.151+		snprint(str, sizeof str, "%s-%ld(SP)", s->name, -a->offset);
  20.152 		break;
  20.153 
  20.154 	case D_PARAM:
  20.155-		sprint(str, "%s+%ld(FP)", s->name, a->offset);
  20.156+		snprint(str, sizeof str, "%s+%ld(FP)", s->name, a->offset);
  20.157 		break;
  20.158 	}
  20.159 out:
    21.1--- a/sys/src/cmd/kl/list.c
    21.2+++ b/sys/src/cmd/kl/list.c
    21.3@@ -20,7 +20,7 @@ prasm(Prog *p)
    21.4 int
    21.5 Pconv(Fmt *fp)
    21.6 {
    21.7-	char str[STRINGSZ], *s;
    21.8+	char str[STRINGSZ];
    21.9 	Prog *p;
   21.10 	int a;
   21.11 
   21.12@@ -28,26 +28,31 @@ Pconv(Fmt *fp)
   21.13 	curp = p;
   21.14 	a = p->as;
   21.15 	if(a == ADATA || a == AINIT || a == ADYNT)
   21.16-		sprint(str, "	%A	%D/%d,%D", a, &p->from, p->reg, &p->to);
   21.17+		snprint(str, sizeof str, "	%A	%D/%d,%D", a, &p->from, p->reg, &p->to);
   21.18 	else{
   21.19-		s = str;
   21.20-		if(p->mark & NOSCHED)
   21.21-			s += sprint(s, "*");
   21.22 		if(p->reg == NREG)
   21.23-			sprint(s, "	%A	%D,%D", a, &p->from, &p->to);
   21.24+			snprint(str, sizeof str, "%s	%A	%D,%D",
   21.25+				p->mark & NOSCHED ? "*" : "", a, 
   21.26+				&p->from, &p->to);
   21.27 		else
   21.28 		if(p->from.type == D_OREG) {
   21.29-			sprint(s, "	%A	%ld(R%d+R%d),%D", a,
   21.30+			snprint(str, sizeof str, "%s	%A	%ld(R%d+R%d),%D",
   21.31+				p->mark & NOSCHED ? "*" : "", a, 
   21.32 				p->from.offset, p->from.reg, p->reg, &p->to);
   21.33 		} else
   21.34 		if(p->to.type == D_OREG) {
   21.35-			sprint(s, "	%A	%D,%ld(R%d+R%d)", a,
   21.36+			snprint(str, sizeof str, "%s	%A	%D,%ld(R%d+R%d)",
   21.37+				p->mark & NOSCHED ? "*" : "", a, 
   21.38 				&p->from, p->to.offset, p->to.reg, p->reg);
   21.39 		} else
   21.40 		if(p->from.type == D_FREG)
   21.41-			sprint(s, "	%A	%D,F%d,%D", a, &p->from, p->reg, &p->to);
   21.42+			snprint(str, sizeof str, "%s	%A	%D,F%d,%D",
   21.43+				p->mark & NOSCHED ? "*" : "", a, 
   21.44+				&p->from, p->reg, &p->to);
   21.45 		else
   21.46-			sprint(s, "	%A	%D,R%d,%D", a, &p->from, p->reg, &p->to);
   21.47+			snprint(str, sizeof str, "%s	%A	%D,R%d,%D",
   21.48+				p->mark & NOSCHED ? "*" : "", a, 
   21.49+				&p->from, p->reg, &p->to);
   21.50 	}
   21.51 	return fmtstrcpy(fp, str);
   21.52 }
   21.53@@ -76,58 +81,58 @@ Dconv(Fmt *fp)
   21.54 	switch(a->type) {
   21.55 
   21.56 	default:
   21.57-		sprint(str, "GOK-type(%d)", a->type);
   21.58+		snprint(str, sizeof str, "GOK-type(%d)", a->type);
   21.59 		break;
   21.60 
   21.61 	case D_NONE:
   21.62 		str[0] = 0;
   21.63 		if(a->name != D_NONE || a->reg != NREG || a->sym != S)
   21.64-			sprint(str, "%N(R%d)(NONE)", a, a->reg);
   21.65+			snprint(str, sizeof str, "%N(R%d)(NONE)", a, a->reg);
   21.66 		break;
   21.67 
   21.68 	case D_CONST:
   21.69 		if(a->reg != NREG)
   21.70-			sprint(str, "$%N(R%d)", a, a->reg);
   21.71+			snprint(str, sizeof str, "$%N(R%d)", a, a->reg);
   21.72 		else
   21.73-			sprint(str, "$%N", a);
   21.74+			snprint(str, sizeof str, "$%N", a);
   21.75 		break;
   21.76 
   21.77 	case D_ASI:
   21.78 		if(a->reg != NREG)
   21.79-			sprint(str, "(R%d,%ld)", a->reg, a->offset);
   21.80+			snprint(str, sizeof str, "(R%d,%ld)", a->reg, a->offset);
   21.81 		else
   21.82-			sprint(str, "(R%d,%ld)", 0, a->offset);
   21.83+			snprint(str, sizeof str, "(R%d,%ld)", 0, a->offset);
   21.84 		break;
   21.85 
   21.86 	case D_OREG:
   21.87 		if(a->reg != NREG)
   21.88-			sprint(str, "%N(R%d)", a, a->reg);
   21.89+			snprint(str, sizeof str, "%N(R%d)", a, a->reg);
   21.90 		else
   21.91-			sprint(str, "%N", a);
   21.92+			snprint(str, sizeof str, "%N", a);
   21.93 		break;
   21.94 
   21.95 	case D_REG:
   21.96-		sprint(str, "R%d", a->reg);
   21.97+		snprint(str, sizeof str, "R%d", a->reg);
   21.98 		if(a->name != D_NONE || a->sym != S)
   21.99-			sprint(str, "%N(R%d)(REG)", a, a->reg);
  21.100+			snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
  21.101 		break;
  21.102 
  21.103 	case D_FREG:
  21.104-		sprint(str, "F%d", a->reg);
  21.105+		snprint(str, sizeof str, "F%d", a->reg);
  21.106 		if(a->name != D_NONE || a->sym != S)
  21.107-			sprint(str, "%N(F%d)(REG)", a, a->reg);
  21.108+			snprint(str, sizeof str, "%N(F%d)(REG)", a, a->reg);
  21.109 		break;
  21.110 
  21.111 	case D_CREG:
  21.112-		sprint(str, "C%d", a->reg);
  21.113+		snprint(str, sizeof str, "C%d", a->reg);
  21.114 		if(a->name != D_NONE || a->sym != S)
  21.115-			sprint(str, "%N(C%d)(REG)", a, a->reg);
  21.116+			snprint(str, sizeof str, "%N(C%d)(REG)", a, a->reg);
  21.117 		break;
  21.118 
  21.119 	case D_PREG:
  21.120-		sprint(str, "P%d", a->reg);
  21.121+		snprint(str, sizeof str, "P%d", a->reg);
  21.122 		if(a->name != D_NONE || a->sym != S)
  21.123-			sprint(str, "%N(P%d)(REG)", a, a->reg);
  21.124+			snprint(str, sizeof str, "%N(P%d)(REG)", a, a->reg);
  21.125 		break;
  21.126 
  21.127 	case D_BRANCH:
  21.128@@ -136,22 +141,22 @@ Dconv(Fmt *fp)
  21.129 			if(v >= INITTEXT)
  21.130 				v -= INITTEXT-HEADR;
  21.131 			if(a->sym != S)
  21.132-				sprint(str, "%s+%.5lux(BRANCH)", a->sym->name, v);
  21.133+				snprint(str, sizeof str, "%s+%.5lux(BRANCH)", a->sym->name, v);
  21.134 			else
  21.135-				sprint(str, "%.5lux(BRANCH)", v);
  21.136+				snprint(str, sizeof str, "%.5lux(BRANCH)", v);
  21.137 		} else
  21.138 			if(a->sym != S)
  21.139-				sprint(str, "%s+%ld(APC)", a->sym->name, a->offset);
  21.140+				snprint(str, sizeof str, "%s+%ld(APC)", a->sym->name, a->offset);
  21.141 			else
  21.142-				sprint(str, "%ld(APC)", a->offset);
  21.143+				snprint(str, sizeof str, "%ld(APC)", a->offset);
  21.144 		break;
  21.145 
  21.146 	case D_FCONST:
  21.147-		sprint(str, "$%lux-%lux", a->ieee.h, a->ieee.l);
  21.148+		snprint(str, sizeof str, "$%lux-%lux", a->ieee.h, a->ieee.l);
  21.149 		break;
  21.150 
  21.151 	case D_SCONST:
  21.152-		sprint(str, "$\"%S\"", a->sval);
  21.153+		snprint(str, sizeof str, "$\"%S\"", a->sval);
  21.154 		break;
  21.155 	}
  21.156 	return fmtstrcpy(fp, str);
  21.157@@ -167,28 +172,28 @@ Nconv(Fmt *fp)
  21.158 	a = va_arg(fp->args, Adr*);
  21.159 	s = a->sym;
  21.160 	if(s == S) {
  21.161-		sprint(str, "%ld", a->offset);
  21.162+		snprint(str, sizeof str, "%ld", a->offset);
  21.163 		goto out;
  21.164 	}
  21.165 	switch(a->name) {
  21.166 	default:
  21.167-		sprint(str, "GOK-name(%d)", a->name);
  21.168+		snprint(str, sizeof str, "GOK-name(%d)", a->name);
  21.169 		break;
  21.170 
  21.171 	case D_EXTERN:
  21.172-		sprint(str, "%s+%ld(SB)", s->name, a->offset);
  21.173+		snprint(str, sizeof str, "%s+%ld(SB)", s->name, a->offset);
  21.174 		break;
  21.175 
  21.176 	case D_STATIC:
  21.177-		sprint(str, "%s<>+%ld(SB)", s->name, a->offset);
  21.178+		snprint(str, sizeof str, "%s<>+%ld(SB)", s->name, a->offset);
  21.179 		break;
  21.180 
  21.181 	case D_AUTO:
  21.182-		sprint(str, "%s-%ld(SP)", s->name, -a->offset);
  21.183+		snprint(str, sizeof str, "%s-%ld(SP)", s->name, -a->offset);
  21.184 		break;
  21.185 
  21.186 	case D_PARAM:
  21.187-		sprint(str, "%s+%ld(FP)", s->name, a->offset);
  21.188+		snprint(str, sizeof str, "%s+%ld(FP)", s->name, a->offset);
  21.189 		break;
  21.190 	}
  21.191 out:
    22.1--- a/sys/src/cmd/kl/obj.c
    22.2+++ b/sys/src/cmd/kl/obj.c
    22.3@@ -248,11 +248,9 @@ objfile(char *file)
    22.4 
    22.5 	if(file[0] == '-' && file[1] == 'l') {
    22.6 		if(debug['9'])
    22.7-			sprint(name, "/%s/lib/lib", thestring);
    22.8+			snprint(name, sizeof name, "/%s/lib/lib%s.a", thestring, file+2);
    22.9 		else
   22.10-			sprint(name, "/usr/%clib/lib", thechar);
   22.11-		strcat(name, file+2);
   22.12-		strcat(name, ".a");
   22.13+			snprint(name, sizeof name, "/usr/%clib/lib%s.a", thechar, file+2);
   22.14 		file = name;
   22.15 	}
   22.16 	if(debug['v'])
   22.17@@ -310,7 +308,7 @@ objfile(char *file)
   22.18 			s = lookup(e+5, 0);
   22.19 			if(s->type != SXREF)
   22.20 				continue;
   22.21-			sprint(pname, "%s(%s)", file, s->name);
   22.22+			snprint(pname, sizeof pname, "%s(%s)", file, s->name);
   22.23 			if(debug['v'])
   22.24 				Bprint(&bso, "%5.2f library: %s\n", cputime(), pname);
   22.25 			Bflush(&bso);
   22.26@@ -440,17 +438,17 @@ addlib(char *obj)
   22.27 		return;
   22.28 
   22.29 	if(histfrog[0]->name[1] == '/') {
   22.30-		sprint(name, "");
   22.31+		name[0] = 0;
   22.32 		i = 1;
   22.33 	} else
   22.34 	if(histfrog[0]->name[1] == '.') {
   22.35-		sprint(name, ".");
   22.36+		snprint(name, sizeof name, ".");
   22.37 		i = 0;
   22.38 	} else {
   22.39 		if(debug['9'])
   22.40-			sprint(name, "/%s/lib", thestring);
   22.41+			snprint(name, sizeof name, "/%s/lib", thestring);
   22.42 		else
   22.43-			sprint(name, "/usr/%clib", thechar);
   22.44+			snprint(name, sizeof name, "/usr/%clib", thechar);
   22.45 		i = 0;
   22.46 	}
   22.47 
   22.48@@ -849,7 +847,7 @@ loop:
   22.49 
   22.50 		if(p->from.type == D_FCONST) {
   22.51 			/* size sb 9 max */
   22.52-			sprint(literal, "$%lux", ieeedtof(&p->from.ieee));
   22.53+			snprint(literal, sizeof literal, "$%lux", ieeedtof(&p->from.ieee));
   22.54 			s = lookup(literal, 0);
   22.55 			if(s->type == 0) {
   22.56 				s->type = SBSS;
   22.57@@ -877,7 +875,7 @@ loop:
   22.58 			goto casedef;
   22.59 		if(p->from.type == D_FCONST) {
   22.60 			/* size sb 18 max */
   22.61-			sprint(literal, "$%lux.%lux",
   22.62+			snprint(literal, sizeof literal, "$%lux.%lux",
   22.63 				p->from.ieee.l, p->from.ieee.h);
   22.64 			s = lookup(literal, 0);
   22.65 			if(s->type == 0) {
    23.1--- a/sys/src/cmd/kl/pass.c
    23.2+++ b/sys/src/cmd/kl/pass.c
    23.3@@ -131,9 +131,9 @@ dodata(void)
    23.4 				continue;
    23.5 			/* size should be 19 max */
    23.6 			if(strlen(s->name) >= 10)	/* has loader address */ 
    23.7-				sprint(literal, "$%p.%lux", s, p->from.offset);
    23.8+				snprint(literal, sizeof literal, "$%p.%lux", s, p->from.offset);
    23.9 			else
   23.10-				sprint(literal, "$%s.%d.%lux", s->name, s->version, p->from.offset);
   23.11+				snprint(literal, sizeof literal, "$%s.%d.%lux", s->name, s->version, p->from.offset);
   23.12 		} else {
   23.13 			if(p->from.name != D_NONE)
   23.14 				continue;
   23.15@@ -145,7 +145,7 @@ dodata(void)
   23.16 			if(!(v & 0xffff))
   23.17 				continue;
   23.18 			/* size should be 9 max */
   23.19-			sprint(literal, "$%lux", v);
   23.20+			snprint(literal, sizeof literal, "$%lux", v);
   23.21 		}
   23.22 		s = lookup(literal, 0);
   23.23 		if(s->type == 0) {
    24.1--- a/sys/src/cmd/qc/list.c
    24.2+++ b/sys/src/cmd/qc/list.c
    24.3@@ -20,20 +20,18 @@ Bconv(Fmt *fp)
    24.4 	Bits bits;
    24.5 	int i;
    24.6 
    24.7-	str[0] = 0;
    24.8+	memset(str, 0, sizeof str);
    24.9 	bits = va_arg(fp->args, Bits);
   24.10 	while(bany(&bits)) {
   24.11 		i = bnum(bits);
   24.12 		if(str[0])
   24.13-			strcat(str, " ");
   24.14+			strncat(str, " ", sizeof str - 1);
   24.15 		if(var[i].sym == S) {
   24.16-			sprint(ss, "$%ld", var[i].offset);
   24.17+			snprint(ss, sizeof ss, "$%ld", var[i].offset);
   24.18 			s = ss;
   24.19 		} else
   24.20 			s = var[i].sym->name;
   24.21-		if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
   24.22-			break;
   24.23-		strcat(str, s);
   24.24+		strncat(str, s, sizeof str - 1);
   24.25 		bits.b[i/32] &= ~(1L << (i%32));
   24.26 	}
   24.27 	return fmtstrcpy(fp, str);
   24.28@@ -49,9 +47,9 @@ Pconv(Fmt *fp)
   24.29 	p = va_arg(fp->args, Prog*);
   24.30 	a = p->as;
   24.31 	if(a == ADATA)
   24.32-		sprint(str, "	%A	%D/%d,%D", a, &p->from, p->reg, &p->to);
   24.33+		snprint(str, sizeof str, "	%A	%D/%d,%D", a, &p->from, p->reg, &p->to);
   24.34 	else if(p->as == ATEXT)
   24.35-		sprint(str, "	%A	%D,%d,%D", a, &p->from, p->reg, &p->to);
   24.36+		snprint(str, sizeof str, "	%A	%D,%d,%D", a, &p->from, p->reg, &p->to);
   24.37 	else {
   24.38 		s = seprint(str, str+sizeof(str), "	%A	%D", a, &p->from);
   24.39 		if(p->reg != NREG)
   24.40@@ -86,57 +84,57 @@ Dconv(Fmt *fp)
   24.41 	switch(a->type) {
   24.42 
   24.43 	default:
   24.44-		sprint(str, "GOK-type(%d)", a->type);
   24.45+		snprint(str, sizeof str, "GOK-type(%d)", a->type);
   24.46 		break;
   24.47 
   24.48 	case D_NONE:
   24.49 		str[0] = 0;
   24.50 		if(a->name != D_NONE || a->reg != NREG || a->sym != S)
   24.51-			sprint(str, "%N(R%d)(NONE)", a, a->reg);
   24.52+			snprint(str, sizeof str, "%N(R%d)(NONE)", a, a->reg);
   24.53 		break;
   24.54 
   24.55 	case D_CONST:
   24.56 		if(a->reg != NREG)
   24.57-			sprint(str, "$%N(R%d)", a, a->reg);
   24.58+			snprint(str, sizeof str, "$%N(R%d)", a, a->reg);
   24.59 		else
   24.60-			sprint(str, "$%N", a);
   24.61+			snprint(str, sizeof str, "$%N", a);
   24.62 		break;
   24.63 
   24.64 	case D_OREG:
   24.65 		if(a->reg != NREG)
   24.66-			sprint(str, "%N(R%d)", a, a->reg);
   24.67+			snprint(str, sizeof str, "%N(R%d)", a, a->reg);
   24.68 		else
   24.69-			sprint(str, "%N", a);
   24.70+			snprint(str, sizeof str, "%N", a);
   24.71 		break;
   24.72 
   24.73 	case D_REG:
   24.74-		sprint(str, "R%d", a->reg);
   24.75+		snprint(str, sizeof str, "R%d", a->reg);
   24.76 		if(a->name != D_NONE || a->sym != S)
   24.77-			sprint(str, "%N(R%d)(REG)", a, a->reg);
   24.78+			snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
   24.79 		break;
   24.80 
   24.81 	case D_FREG:
   24.82-		sprint(str, "F%d", a->reg);
   24.83+		snprint(str, sizeof str, "F%d", a->reg);
   24.84 		if(a->name != D_NONE || a->sym != S)
   24.85-			sprint(str, "%N(F%d)(REG)", a, a->reg);
   24.86+			snprint(str, sizeof str, "%N(F%d)(REG)", a, a->reg);
   24.87 		break;
   24.88 
   24.89 	case D_CREG:
   24.90-		sprint(str, "C%d", a->reg);
   24.91+		snprint(str, sizeof str, "C%d", a->reg);
   24.92 		if(a->name != D_NONE || a->sym != S)
   24.93-			sprint(str, "%N(C%d)(REG)", a, a->reg);
   24.94+			snprint(str, sizeof str, "%N(C%d)(REG)", a, a->reg);
   24.95 		break;
   24.96 
   24.97 	case D_BRANCH:
   24.98-		sprint(str, "%ld(PC)", a->offset-pc);
   24.99+		snprint(str, sizeof str, "%ld(PC)", a->offset-pc);
  24.100 		break;
  24.101 
  24.102 	case D_FCONST:
  24.103-		sprint(str, "$%.17e", a->dval);
  24.104+		snprint(str, sizeof str, "$%.17e", a->dval);
  24.105 		break;
  24.106 
  24.107 	case D_SCONST:
  24.108-		sprint(str, "$\"%S\"", a->sval);
  24.109+		snprint(str, sizeof str, "$\"%S\"", a->sval);
  24.110 		break;
  24.111 	}
  24.112 	return fmtstrcpy(fp, str);
  24.113@@ -210,32 +208,32 @@ Nconv(Fmt *fp)
  24.114 				l = b;
  24.115 			}
  24.116 			if(n < 2) {
  24.117-				sprint(str, "%#lux", a->offset);
  24.118+				snprint(str, sizeof str, "%#lux", a->offset);
  24.119 				goto out;
  24.120 			}
  24.121 		}
  24.122-		sprint(str, "%ld", a->offset);
  24.123+		snprint(str, sizeof str, "%ld", a->offset);
  24.124 		goto out;
  24.125 	}
  24.126 	switch(a->name) {
  24.127 	default:
  24.128-		sprint(str, "GOK-name(%d)", a->name);
  24.129+		snprint(str, sizeof str, "GOK-name(%d)", a->name);
  24.130 		break;
  24.131 
  24.132 	case D_EXTERN:
  24.133-		sprint(str, "%s+%ld(SB)", s->name, a->offset);
  24.134+		snprint(str, sizeof str, "%s+%ld(SB)", s->name, a->offset);
  24.135 		break;
  24.136 
  24.137 	case D_STATIC:
  24.138-		sprint(str, "%s<>+%ld(SB)", s->name, a->offset);
  24.139+		snprint(str, sizeof str, "%s<>+%ld(SB)", s->name, a->offset);
  24.140 		break;
  24.141 
  24.142 	case D_AUTO:
  24.143-		sprint(str, "%s-%ld(SP)", s->name, -a->offset);
  24.144+		snprint(str, sizeof str, "%s-%ld(SP)", s->name, -a->offset);
  24.145 		break;
  24.146 
  24.147 	case D_PARAM:
  24.148-		sprint(str, "%s+%ld(FP)", s->name, a->offset);
  24.149+		snprint(str, sizeof str, "%s+%ld(FP)", s->name, a->offset);
  24.150 		break;
  24.151 	}
  24.152 out:
    25.1--- a/sys/src/cmd/ql/list.c
    25.2+++ b/sys/src/cmd/ql/list.c
    25.3@@ -21,7 +21,7 @@ prasm(Prog *p)
    25.4 int
    25.5 Pconv(Fmt *fp)
    25.6 {
    25.7-	char str[STRINGSZ], *s;
    25.8+	char str[STRINGSZ];
    25.9 	Prog *p;
   25.10 	int a;
   25.11 
   25.12@@ -29,28 +29,34 @@ Pconv(Fmt *fp)
   25.13 	curp = p;
   25.14 	a = p->as;
   25.15 	if(a == ADATA || a == AINIT || a == ADYNT)
   25.16-		sprint(str, "(%d)	%A	%D/%d,%D", p->line, a, &p->from, p->reg, &p->to);
   25.17+		snprint(str, sizeof str, "(%d)	%A	%D/%d,%D", p->line, a, &p->from, p->reg, &p->to);
   25.18 	else {
   25.19-		s = str;
   25.20-		if(p->mark & NOSCHED)
   25.21-			s += sprint(s, "*");
   25.22 		if(p->reg == NREG && p->from3.type == D_NONE)
   25.23-			sprint(s, "(%d)	%A	%D,%D", p->line, a, &p->from, &p->to);
   25.24+			snprint(str, sizeof str, "%s(%d)	%A	%D,%D", 
   25.25+				p->mark & NOSCHED ? "*" : "", p->line, a, 
   25.26+				&p->from, &p->to);
   25.27 		else
   25.28 		if(a != ATEXT && p->from.type == D_OREG) {
   25.29-			sprint(s, "(%d)	%A	%ld(R%d+R%d),%D", p->line, a,
   25.30+			snprint(str, sizeof str, "%s(%d)	%A	%ld(R%d+R%d),%D",
   25.31+				p->mark & NOSCHED ? "*" : "", p->line, a, 
   25.32 				p->from.offset, p->from.reg, p->reg, &p->to);
   25.33 		} else
   25.34 		if(p->to.type == D_OREG) {
   25.35-			sprint(s, "(%d)	%A	%D,%ld(R%d+R%d)", p->line, a,
   25.36-					&p->from, p->to.offset, p->to.reg, p->reg);
   25.37+			snprint(str, sizeof str, "%s(%d)	%A	%D,%ld(R%d+R%d)",
   25.38+				p->mark & NOSCHED ? "*" : "", p->line, a, 
   25.39+				&p->from, p->to.offset, p->to.reg, p->reg);
   25.40 		} else {
   25.41-			s += sprint(s, "(%d)	%A	%D", p->line, a, &p->from);
   25.42+			snprint(str, sizeof str, "%s(%d)	%A	%D", 
   25.43+				p->mark & NOSCHED ? "*" : "", p->line, a, 
   25.44+				&p->from);
   25.45 			if(p->reg != NREG)
   25.46-				s += sprint(s, ",%c%d", p->from.type==D_FREG?'F':'R', p->reg);
   25.47+				snprint(str + strlen(str), sizeof(str) - strlen(str),
   25.48+					",%c%d", p->from.type==D_FREG?'F':'R', p->reg);
   25.49 			if(p->from3.type != D_NONE)
   25.50-				s += sprint(s, ",%D", &p->from3);
   25.51-			sprint(s, ",%D", &p->to);
   25.52+				snprint(str + strlen(str), sizeof(str) - strlen(str),
   25.53+					",%D", &p->from3);
   25.54+			snprint(str + strlen(str), sizeof(str) - strlen(str),
   25.55+				",%D", &p->to);
   25.56 		}
   25.57 	}
   25.58 	return fmtstrcpy(fp, str);
   25.59@@ -80,97 +86,97 @@ Dconv(Fmt *fp)
   25.60 	switch(a->type) {
   25.61 
   25.62 	default:
   25.63-		sprint(str, "GOK-type(%d)", a->type);
   25.64+		snprint(str, sizeof str, "GOK-type(%d)", a->type);
   25.65 		break;
   25.66 
   25.67 	case D_NONE:
   25.68 		str[0] = 0;
   25.69 		if(a->name != D_NONE || a->reg != NREG || a->sym != S)
   25.70-			sprint(str, "%N(R%d)(NONE)", a, a->reg);
   25.71+			snprint(str, sizeof str, "%N(R%d)(NONE)", a, a->reg);
   25.72 		break;
   25.73 
   25.74 	case D_CONST:
   25.75 		if(a->reg != NREG)
   25.76-			sprint(str, "$%N(R%d)", a, a->reg);
   25.77+			snprint(str, sizeof str, "$%N(R%d)", a, a->reg);
   25.78 		else
   25.79-			sprint(str, "$%N", a);
   25.80+			snprint(str, sizeof str, "$%N", a);
   25.81 		break;
   25.82 
   25.83 	case D_OREG:
   25.84 		if(a->reg != NREG)
   25.85-			sprint(str, "%N(R%d)", a, a->reg);
   25.86+			snprint(str, sizeof str, "%N(R%d)", a, a->reg);
   25.87 		else
   25.88-			sprint(str, "%N", a);
   25.89+			snprint(str, sizeof str, "%N", a);
   25.90 		break;
   25.91 
   25.92 	case D_REG:
   25.93-		sprint(str, "R%d", a->reg);
   25.94+		snprint(str, sizeof str, "R%d", a->reg);
   25.95 		if(a->name != D_NONE || a->sym != S)
   25.96-			sprint(str, "%N(R%d)(REG)", a, a->reg);
   25.97+			snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
   25.98 		break;
   25.99 
  25.100 	case D_FREG:
  25.101-		sprint(str, "F%d", a->reg);
  25.102+		snprint(str, sizeof str, "F%d", a->reg);
  25.103 		if(a->name != D_NONE || a->sym != S)
  25.104-			sprint(str, "%N(F%d)(REG)", a, a->reg);
  25.105+			snprint(str, sizeof str, "%N(F%d)(REG)", a, a->reg);
  25.106 		break;
  25.107 
  25.108 	case D_CREG:
  25.109 		if(a->reg == NREG)
  25.110 			strcpy(str, "CR");
  25.111 		else
  25.112-			sprint(str, "CR%d", a->reg);
  25.113+			snprint(str, sizeof str, "CR%d", a->reg);
  25.114 		if(a->name != D_NONE || a->sym != S)
  25.115-			sprint(str, "%N(C%d)(REG)", a, a->reg);
  25.116+			snprint(str, sizeof str, "%N(C%d)(REG)", a, a->reg);
  25.117 		break;
  25.118 
  25.119 	case D_SPR:
  25.120 		if(a->name == D_NONE && a->sym == S) {
  25.121 			switch(a->offset) {
  25.122-			case D_XER: sprint(str, "XER"); break;
  25.123-			case D_LR: sprint(str, "LR"); break;
  25.124-			case D_CTR: sprint(str, "CTR"); break;
  25.125-			default: sprint(str, "SPR(%ld)", a->offset); break;
  25.126+			case D_XER: snprint(str, sizeof str, "XER"); break;
  25.127+			case D_LR: snprint(str, sizeof str, "LR"); break;
  25.128+			case D_CTR: snprint(str, sizeof str, "CTR"); break;
  25.129+			default: snprint(str, sizeof str, "SPR(%ld)", a->offset); break;
  25.130 			}
  25.131 			break;
  25.132 		}
  25.133-		sprint(str, "SPR-GOK(%d)", a->reg);
  25.134+		snprint(str, sizeof str, "SPR-GOK(%d)", a->reg);
  25.135 		if(a->name != D_NONE || a->sym != S)
  25.136-			sprint(str, "%N(SPR-GOK%d)(REG)", a, a->reg);
  25.137+			snprint(str, sizeof str, "%N(SPR-GOK%d)(REG)", a, a->reg);
  25.138 		break;
  25.139 
  25.140 	case D_DCR:
  25.141 		if(a->name == D_NONE && a->sym == S) {
  25.142 			if(a->reg == NREG)
  25.143-				sprint(str, "DCR(%ld)", a->offset);
  25.144+				snprint(str, sizeof str, "DCR(%ld)", a->offset);
  25.145 			else
  25.146-				sprint(str, "DCR(R%d)", a->reg);
  25.147+				snprint(str, sizeof str, "DCR(R%d)", a->reg);
  25.148 			break;
  25.149 		}
  25.150-		sprint(str, "DCR-GOK(%d)", a->reg);
  25.151+		snprint(str, sizeof str, "DCR-GOK(%d)", a->reg);
  25.152 		if(a->name != D_NONE || a->sym != S)
  25.153-			sprint(str, "%N(DCR-GOK%d)(REG)", a, a->reg);
  25.154+			snprint(str, sizeof str, "%N(DCR-GOK%d)(REG)", a, a->reg);
  25.155 		break;
  25.156 
  25.157 	case D_OPT:
  25.158-		sprint(str, "OPT(%d)", a->reg);
  25.159+		snprint(str, sizeof str, "OPT(%d)", a->reg);
  25.160 		break;
  25.161 
  25.162 	case D_FPSCR:
  25.163 		if(a->reg == NREG)
  25.164 			strcpy(str, "FPSCR");
  25.165 		else
  25.166-			sprint(str, "FPSCR(%d)", a->reg);
  25.167+			snprint(str, sizeof str, "FPSCR(%d)", a->reg);
  25.168 		break;
  25.169 
  25.170 	case D_MSR:
  25.171-		sprint(str, "MSR");
  25.172+		snprint(str, sizeof str, "MSR");
  25.173 		break;
  25.174 
  25.175 	case D_SREG:
  25.176-		sprint(str, "SREG(%d)", a->reg);
  25.177+		snprint(str, sizeof str, "SREG(%d)", a->reg);
  25.178 		if(a->name != D_NONE || a->sym != S)
  25.179-			sprint(str, "%N(SREG%d)(REG)", a, a->reg);
  25.180+			snprint(str, sizeof str, "%N(SREG%d)(REG)", a, a->reg);
  25.181 		break;
  25.182 
  25.183 	case D_BRANCH:
  25.184@@ -179,22 +185,22 @@ Dconv(Fmt *fp)
  25.185 			if(v >= INITTEXT)
  25.186 				v -= INITTEXT-HEADR;
  25.187 			if(a->sym != S)
  25.188-				sprint(str, "%s+%.5lux(BRANCH)", a->sym->name, v);
  25.189+				snprint(str, sizeof str, "%s+%.5lux(BRANCH)", a->sym->name, v);
  25.190 			else
  25.191-				sprint(str, "%.5lux(BRANCH)", v);
  25.192+				snprint(str, sizeof str, "%.5lux(BRANCH)", v);
  25.193 		} else
  25.194 			if(a->sym != S)
  25.195-				sprint(str, "%s+%ld(APC)", a->sym->name, a->offset);
  25.196+				snprint(str, sizeof str, "%s+%ld(APC)", a->sym->name, a->offset);
  25.197 			else
  25.198-				sprint(str, "%ld(APC)", a->offset);
  25.199+				snprint(str, sizeof str, "%ld(APC)", a->offset);
  25.200 		break;
  25.201 
  25.202 	case D_FCONST:
  25.203-		sprint(str, "$%lux-%lux", a->ieee.h, a->ieee.l);
  25.204+		snprint(str, sizeof str, "$%lux-%lux", a->ieee.h, a->ieee.l);
  25.205 		break;
  25.206 
  25.207 	case D_SCONST:
  25.208-		sprint(str, "$\"%S\"", a->sval);
  25.209+		snprint(str, sizeof str, "$\"%S\"", a->sval);
  25.210 		break;
  25.211 	}
  25.212 	return fmtstrcpy(fp, str);
  25.213@@ -210,28 +216,28 @@ Nconv(Fmt *fp)
  25.214 	a = va_arg(fp->args, Adr*);
  25.215 	s = a->sym;
  25.216 	if(s == S) {
  25.217-		sprint(str, "%ld", a->offset);
  25.218+		snprint(str, sizeof str, "%ld", a->offset);
  25.219 		goto out;
  25.220 	}
  25.221 	switch(a->name) {
  25.222 	default:
  25.223-		sprint(str, "GOK-name(%d)", a->name);
  25.224+		snprint(str, sizeof str, "GOK-name(%d)", a->name);
  25.225 		break;
  25.226 
  25.227 	case D_EXTERN:
  25.228-		sprint(str, "%s+%ld(SB)", s->name, a->offset);
  25.229+		snprint(str, sizeof str, "%s+%ld(SB)", s->name, a->offset);
  25.230 		break;
  25.231 
  25.232 	case D_STATIC:
  25.233-		sprint(str, "%s<>+%ld(SB)", s->name, a->offset);
  25.234+		snprint(str, sizeof str, "%s<>+%ld(SB)", s->name, a->offset);
  25.235 		break;
  25.236 
  25.237 	case D_AUTO:
  25.238-		sprint(str, "%s-%ld(SP)", s->name, -a->offset);
  25.239+		snprint(str, sizeof str, "%s-%ld(SP)", s->name, -a->offset);
  25.240 		break;
  25.241 
  25.242 	case D_PARAM:
  25.243-		sprint(str, "%s+%ld(FP)", s->name, a->offset);
  25.244+		snprint(str, sizeof str, "%s+%ld(FP)", s->name, a->offset);
  25.245 		break;
  25.246 	}
  25.247 out:
    26.1--- a/sys/src/cmd/ql/obj.c
    26.2+++ b/sys/src/cmd/ql/obj.c
    26.3@@ -327,11 +327,9 @@ objfile(char *file)
    26.4 
    26.5 	if(file[0] == '-' && file[1] == 'l') {
    26.6 		if(debug['9'])
    26.7-			sprint(name, "/%s/lib/lib", thestring);
    26.8+			snprint(name, sizeof name, "/%s/lib/lib%s.a", thestring, file+2);
    26.9 		else
   26.10-			sprint(name, "/usr/%clib/lib", thechar);
   26.11-		strcat(name, file+2);
   26.12-		strcat(name, ".a");
   26.13+			snprint(name, sizeof name, "/usr/%clib/lib%s.a", thechar, file+2);
   26.14 		file = name;
   26.15 	}
   26.16 	if(debug['v'])
   26.17@@ -389,7 +387,7 @@ objfile(char *file)
   26.18 			s = lookup(e+5, 0);
   26.19 			if(s->type != SXREF)
   26.20 				continue;
   26.21-			sprint(pname, "%s(%s)", file, s->name);
   26.22+			snprint(pname, sizeof pname, "%s(%s)", file, s->name);
   26.23 			if(debug['v'])
   26.24 				Bprint(&bso, "%5.2f library: %s\n", cputime(), pname);
   26.25 			Bflush(&bso);
   26.26@@ -523,17 +521,17 @@ addlib(char *obj)
   26.27 		return;
   26.28 
   26.29 	if(histfrog[0]->name[1] == '/') {
   26.30-		sprint(name, "");
   26.31+		name[0] = 0;
   26.32 		i = 1;
   26.33 	} else
   26.34 	if(histfrog[0]->name[1] == '.') {
   26.35-		sprint(name, ".");
   26.36+		snprint(name, sizeof name, ".");
   26.37 		i = 0;
   26.38 	} else {
   26.39 		if(debug['9'])
   26.40-			sprint(name, "/%s/lib", thestring);
   26.41+			snprint(name, sizeof name, "/%s/lib", thestring);
   26.42 		else
   26.43-			sprint(name, "/usr/%clib", thechar);
   26.44+			snprint(name, sizeof name, "/usr/%clib", thechar);
   26.45 		i = 0;
   26.46 	}
   26.47 
   26.48@@ -961,7 +959,7 @@ loop:
   26.49 
   26.50 		if(p->from.type == D_FCONST) {
   26.51 			/* size sb 9 max */
   26.52-			sprint(literal, "$%lux", ieeedtof(&p->from.ieee));
   26.53+			snprint(literal, sizeof literal, "$%lux", ieeedtof(&p->from.ieee));
   26.54 			s = lookup(literal, 0);
   26.55 			if(s->type == 0) {
   26.56 				s->type = SBSS;
   26.57@@ -989,7 +987,7 @@ loop:
   26.58 			goto casedef;
   26.59 		if(p->from.type == D_FCONST) {
   26.60 			/* size sb 18 max */
   26.61-			sprint(literal, "$%lux.%lux",
   26.62+			snprint(literal, sizeof literal, "$%lux.%lux",
   26.63 				p->from.ieee.l, p->from.ieee.h);
   26.64 			s = lookup(literal, 0);
   26.65 			if(s->type == 0) {
    27.1--- a/sys/src/cmd/ql/pass.c
    27.2+++ b/sys/src/cmd/ql/pass.c
    27.3@@ -131,9 +131,9 @@ dodata(void)
    27.4 				continue;
    27.5 			/* size should be 19 max */
    27.6 			if(strlen(s->name) >= 10)	/* has loader address */ 
    27.7-				sprint(literal, "$%p.%lux", s, p->from.offset);
    27.8+				snprint(literal, sizeof literal, "$%p.%lux", s, p->from.offset);
    27.9 			else
   27.10-				sprint(literal, "$%s.%d.%lux", s->name, s->version, p->from.offset);
   27.11+				snprint(literal, sizeof literal, "$%s.%d.%lux", s->name, s->version, p->from.offset);
   27.12 		} else {
   27.13 			if(p->from.name != D_NONE)
   27.14 				continue;
   27.15@@ -147,7 +147,7 @@ dodata(void)
   27.16 			if(v)
   27.17 				continue;	/* quicker to build it than load it */
   27.18 			/* size should be 9 max */
   27.19-			sprint(literal, "$%lux", v);
   27.20+			snprint(literal, sizeof literal, "$%lux", v);
   27.21 		}
   27.22 		s = lookup(literal, 0);
   27.23 		if(s->type == 0) {
    28.1--- a/sys/src/cmd/vc/list.c
    28.2+++ b/sys/src/cmd/vc/list.c
    28.3@@ -19,20 +19,18 @@ Bconv(Fmt *fp)
    28.4 	Bits bits;
    28.5 	int i;
    28.6 
    28.7-	str[0] = 0;
    28.8+	memset(str, 0, sizeof str);
    28.9 	bits = va_arg(fp->args, Bits);
   28.10 	while(bany(&bits)) {
   28.11 		i = bnum(bits);
   28.12 		if(str[0])
   28.13-			strcat(str, " ");
   28.14+			strncat(str, " ", sizeof str - 1);
   28.15 		if(var[i].sym == S) {
   28.16-			sprint(ss, "$%ld", var[i].offset);
   28.17+			snprint(ss, sizeof ss, "$%ld", var[i].offset);
   28.18 			s = ss;
   28.19 		} else
   28.20 			s = var[i].sym->name;
   28.21-		if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
   28.22-			break;
   28.23-		strcat(str, s);
   28.24+		strncat(str, s, sizeof str - 1);
   28.25 		bits.b[i/32] &= ~(1L << (i%32));
   28.26 	}
   28.27 	return fmtstrcpy(fp, str);
   28.28@@ -48,18 +46,18 @@ Pconv(Fmt *fp)
   28.29 	p = va_arg(fp->args, Prog*);
   28.30 	a = p->as;
   28.31 	if(a == ADATA)
   28.32-		sprint(str, "	%A	%D/%d,%D", a, &p->from, p->reg, &p->to);
   28.33+		snprint(str, sizeof str, "	%A	%D/%d,%D", a, &p->from, p->reg, &p->to);
   28.34 	else
   28.35 	if(p->as == ATEXT)
   28.36-		sprint(str, "	%A	%D,%d,%D", a, &p->from, p->reg, &p->to);
   28.37+		snprint(str, sizeof str, "	%A	%D,%d,%D", a, &p->from, p->reg, &p->to);
   28.38 	else
   28.39 	if(p->reg == NREG)
   28.40-		sprint(str, "	%A	%D,%D", a, &p->from, &p->to);
   28.41+		snprint(str, sizeof str, "	%A	%D,%D", a, &p->from, &p->to);
   28.42 	else
   28.43 	if(p->from.type != D_FREG)
   28.44-		sprint(str, "	%A	%D,R%d,%D", a, &p->from, p->reg, &p->to);
   28.45+		snprint(str, sizeof str, "	%A	%D,R%d,%D", a, &p->from, p->reg, &p->to);
   28.46 	else
   28.47-		sprint(str, "	%A	%D,F%d,%D", a, &p->from, p->reg, &p->to);
   28.48+		snprint(str, sizeof str, "	%A	%D,F%d,%D", a, &p->from, p->reg, &p->to);
   28.49 	return fmtstrcpy(fp, str);
   28.50 }
   28.51 
   28.52@@ -86,69 +84,69 @@ Dconv(Fmt *fp)
   28.53 	switch(a->type) {
   28.54 
   28.55 	default:
   28.56-		sprint(str, "GOK-type(%d)", a->type);
   28.57+		snprint(str, sizeof str, "GOK-type(%d)", a->type);
   28.58 		break;
   28.59 
   28.60 	case D_NONE:
   28.61 		str[0] = 0;
   28.62 		if(a->name != D_NONE || a->reg != NREG || a->sym != S)
   28.63-			sprint(str, "%N(R%d)(NONE)", a, a->reg);
   28.64+			snprint(str, sizeof str, "%N(R%d)(NONE)", a, a->reg);
   28.65 		break;
   28.66 
   28.67 	case D_CONST:
   28.68 		if(a->reg != NREG)
   28.69-			sprint(str, "$%N(R%d)", a, a->reg);
   28.70+			snprint(str, sizeof str, "$%N(R%d)", a, a->reg);
   28.71 		else
   28.72-			sprint(str, "$%N", a);
   28.73+			snprint(str, sizeof str, "$%N", a);
   28.74 		break;
   28.75 
   28.76 	case D_OREG:
   28.77 		if(a->reg != NREG)
   28.78-			sprint(str, "%N(R%d)", a, a->reg);
   28.79+			snprint(str, sizeof str, "%N(R%d)", a, a->reg);
   28.80 		else
   28.81-			sprint(str, "%N", a);
   28.82+			snprint(str, sizeof str, "%N", a);
   28.83 		break;
   28.84 
   28.85 	case D_REG:
   28.86-		sprint(str, "R%d", a->reg);
   28.87+		snprint(str, sizeof str, "R%d", a->reg);
   28.88 		if(a->name != D_NONE || a->sym != S)
   28.89-			sprint(str, "%N(R%d)(REG)", a, a->reg);
   28.90+			snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
   28.91 		break;
   28.92 
   28.93 	case D_FREG:
   28.94-		sprint(str, "F%d", a->reg);
   28.95+		snprint(str, sizeof str, "F%d", a->reg);
   28.96 		if(a->name != D_NONE || a->sym != S)
   28.97-			sprint(str, "%N(R%d)(REG)", a, a->reg);
   28.98+			snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
   28.99 		break;
  28.100 
  28.101 	case D_FCREG:
  28.102-		sprint(str, "FCR%d", a->reg);
  28.103+		snprint(str, sizeof str, "FCR%d", a->reg);
  28.104 		if(a->name != D_NONE || a->sym != S)
  28.105-			sprint(str, "%N(R%d)(REG)", a, a->reg);
  28.106+			snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
  28.107 		break;
  28.108 
  28.109 	case D_LO:
  28.110-		sprint(str, "LO");
  28.111+		snprint(str, sizeof str, "LO");
  28.112 		if(a->name != D_NONE || a->sym != S)
  28.113-			sprint(str, "%N(LO)(REG)", a);
  28.114+			snprint(str, sizeof str, "%N(LO)(REG)", a);
  28.115 		break;
  28.116 
  28.117 	case D_HI:
  28.118-		sprint(str, "HI");
  28.119+		snprint(str, sizeof str, "HI");
  28.120 		if(a->name != D_NONE || a->sym != S)
  28.121-			sprint(str, "%N(HI)(REG)", a);
  28.122+			snprint(str, sizeof str, "%N(HI)(REG)", a);
  28.123 		break;
  28.124 
  28.125 	case D_BRANCH:
  28.126-		sprint(str, "%ld(PC)", a->offset-pc);
  28.127+		snprint(str, sizeof str, "%ld(PC)", a->offset-pc);
  28.128 		break;
  28.129 
  28.130 	case D_FCONST:
  28.131-		sprint(str, "$%.17e", a->dval);
  28.132+		snprint(str, sizeof str, "$%.17e", a->dval);
  28.133 		break;
  28.134 
  28.135 	case D_SCONST:
  28.136-		sprint(str, "$\"%S\"", a->sval);
  28.137+		snprint(str, sizeof str, "$\"%S\"", a->sval);
  28.138 		break;
  28.139 	}
  28.140 	return fmtstrcpy(fp, str);
  28.141@@ -211,32 +209,32 @@ Nconv(Fmt *fp)
  28.142 	a = va_arg(fp->args, Adr*);
  28.143 	s = a->sym;
  28.144 	if(s == S) {
  28.145-		sprint(str, "%ld", a->offset);
  28.146+		snprint(str, sizeof str, "%ld", a->offset);
  28.147 		goto out;
  28.148 	}
  28.149 	switch(a->name) {
  28.150 	default:
  28.151-		sprint(str, "GOK-name(%d)", a->name);
  28.152+		snprint(str, sizeof str, "GOK-name(%d)", a->name);
  28.153 		break;
  28.154 
  28.155 	case D_NONE:
  28.156-		sprint(str, "%ld", a->offset);
  28.157+		snprint(str, sizeof str, "%ld", a->offset);
  28.158 		break;
  28.159 
  28.160 	case D_EXTERN:
  28.161-		sprint(str, "%s+%ld(SB)", s->name, a->offset);
  28.162+		snprint(str, sizeof str, "%s+%ld(SB)", s->name, a->offset);
  28.163 		break;
  28.164 
  28.165 	case D_STATIC:
  28.166-		sprint(str, "%s<>+%ld(SB)", s->name, a->offset);
  28.167+		snprint(str, sizeof str, "%s<>+%ld(SB)", s->name, a->offset);
  28.168 		break;
  28.169 
  28.170 	case D_AUTO:
  28.171-		sprint(str, "%s-%ld(SP)", s->name, -a->offset);
  28.172+		snprint(str, sizeof str, "%s-%ld(SP)", s->name, -a->offset);
  28.173 		break;
  28.174 
  28.175 	case D_PARAM:
  28.176-		sprint(str, "%s+%ld(FP)", s->name, a->offset);
  28.177+		snprint(str, sizeof str, "%s+%ld(FP)", s->name, a->offset);
  28.178 		break;
  28.179 	}
  28.180 out:
    29.1--- a/sys/src/cmd/vl/list.c
    29.2+++ b/sys/src/cmd/vl/list.c
    29.3@@ -20,7 +20,7 @@ prasm(Prog *p)
    29.4 int
    29.5 Pconv(Fmt *fp)
    29.6 {
    29.7-	char str[STRINGSZ], *s;
    29.8+	char str[STRINGSZ];
    29.9 	Prog *p;
   29.10 	int a;
   29.11 
   29.12@@ -28,22 +28,21 @@ Pconv(Fmt *fp)
   29.13 	curp = p;
   29.14 	a = p->as;
   29.15 	if(a == ADATA || a == ADYNT || a == AINIT)
   29.16-		sprint(str, "(%ld)	%A	%D/%d,%D",
   29.17+		snprint(str, sizeof str, "(%ld)	%A	%D/%d,%D",
   29.18 			p->line, a, &p->from, p->reg, &p->to);
   29.19 	else{
   29.20-		s = str;
   29.21-		s += sprint(s, "(%ld)", p->line);
   29.22-		if(p->mark & NOSCHED)
   29.23-			s += sprint(s, "*");
   29.24 		if(p->reg == NREG)
   29.25-			sprint(s, "	%A	%D,%D",
   29.26+			snprint(str, sizeof str, "(%ld)%s	%A	%D,%D",
   29.27+				p->line, p->mark & NOSCHED ? "*" : "",
   29.28 				a, &p->from, &p->to);
   29.29 		else
   29.30 		if(p->from.type != D_FREG)
   29.31-			sprint(s, "	%A	%D,R%d,%D",
   29.32+			snprint(str, sizeof str, "(%ld)%s	%A	%D,R%d,%D",
   29.33+				p->line, p->mark & NOSCHED ? "*" : "",
   29.34 				a, &p->from, p->reg, &p->to);
   29.35 		else
   29.36-			sprint(s, "	%A	%D,F%d,%D",
   29.37+			snprint(str, sizeof str, "(%ld)%s	%A	%D,F%d,%D",
   29.38+				p->line, p->mark & NOSCHED ? "*" : "",
   29.39 				a, &p->from, p->reg, &p->to);
   29.40 	}
   29.41 	return fmtstrcpy(fp, str);
   29.42@@ -73,68 +72,68 @@ Dconv(Fmt *fp)
   29.43 	switch(a->type) {
   29.44 
   29.45 	default:
   29.46-		sprint(str, "GOK-type(%d)", a->type);
   29.47+		snprint(str, sizeof str, "GOK-type(%d)", a->type);
   29.48 		break;
   29.49 
   29.50 	case D_NONE:
   29.51 		str[0] = 0;
   29.52 		if(a->name != D_NONE || a->reg != NREG || a->sym != S)
   29.53-			sprint(str, "%N(R%d)(NONE)", a, a->reg);
   29.54+			snprint(str, sizeof str, "%N(R%d)(NONE)", a, a->reg);
   29.55 		break;
   29.56 
   29.57 	case D_CONST:
   29.58-		sprint(str, "$%N", a);
   29.59+		snprint(str, sizeof str, "$%N", a);
   29.60 		if(a->reg != NREG)
   29.61-			sprint(str, "%N(R%d)(CONST)", a, a->reg);
   29.62+			snprint(str, sizeof str, "%N(R%d)(CONST)", a, a->reg);
   29.63 		break;
   29.64 
   29.65 	case D_OCONST:
   29.66-		sprint(str, "$*$%N", a);
   29.67+		snprint(str, sizeof str, "$*$%N", a);
   29.68 		if(a->reg != NREG)
   29.69-			sprint(str, "%N(R%d)(CONST)", a, a->reg);
   29.70+			snprint(str, sizeof str, "%N(R%d)(CONST)", a, a->reg);
   29.71 		break;
   29.72 
   29.73 	case D_OREG:
   29.74 		if(a->reg != NREG)
   29.75-			sprint(str, "%N(R%d)", a, a->reg);
   29.76+			snprint(str, sizeof str, "%N(R%d)", a, a->reg);
   29.77 		else
   29.78-			sprint(str, "%N", a);
   29.79+			snprint(str, sizeof str, "%N", a);
   29.80 		break;
   29.81 
   29.82 	case D_REG:
   29.83-		sprint(str, "R%d", a->reg);
   29.84+		snprint(str, sizeof str, "R%d", a->reg);
   29.85 		if(a->name != D_NONE || a->sym != S)
   29.86-			sprint(str, "%N(R%d)(REG)", a, a->reg);
   29.87+			snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
   29.88 		break;
   29.89 
   29.90 	case D_MREG:
   29.91-		sprint(str, "M%d", a->reg);
   29.92+		snprint(str, sizeof str, "M%d", a->reg);
   29.93 		if(a->name != D_NONE || a->sym != S)
   29.94-			sprint(str, "%N(R%d)(REG)", a, a->reg);
   29.95+			snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
   29.96 		break;
   29.97 
   29.98 	case D_FREG:
   29.99-		sprint(str, "F%d", a->reg);
  29.100+		snprint(str, sizeof str, "F%d", a->reg);
  29.101 		if(a->name != D_NONE || a->sym != S)
  29.102-			sprint(str, "%N(R%d)(REG)", a, a->reg);
  29.103+			snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
  29.104 		break;
  29.105 
  29.106 	case D_FCREG:
  29.107-		sprint(str, "FC%d", a->reg);
  29.108+		snprint(str, sizeof str, "FC%d", a->reg);
  29.109 		if(a->name != D_NONE || a->sym != S)
  29.110-			sprint(str, "%N(R%d)(REG)", a, a->reg);
  29.111+			snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
  29.112 		break;
  29.113 
  29.114 	case D_LO:
  29.115-		sprint(str, "LO");
  29.116+		snprint(str, sizeof str, "LO");
  29.117 		if(a->name != D_NONE || a->sym != S)
  29.118-			sprint(str, "%N(LO)(REG)", a);
  29.119+			snprint(str, sizeof str, "%N(LO)(REG)", a);
  29.120 		break;
  29.121 
  29.122 	case D_HI:
  29.123-		sprint(str, "HI");
  29.124+		snprint(str, sizeof str, "HI");
  29.125 		if(a->name != D_NONE || a->sym != S)
  29.126-			sprint(str, "%N(HI)(REG)", a);
  29.127+			snprint(str, sizeof str, "%N(HI)(REG)", a);
  29.128 		break;
  29.129 
  29.130 	case D_BRANCH:	/* botch */
  29.131@@ -143,22 +142,22 @@ Dconv(Fmt *fp)
  29.132 			if(v >= INITTEXT)
  29.133 				v -= INITTEXT-HEADR;
  29.134 			if(a->sym != S)
  29.135-				sprint(str, "%s+%.5lux(BRANCH)", a->sym->name, v);
  29.136+				snprint(str, sizeof str, "%s+%.5lux(BRANCH)", a->sym->name, v);
  29.137 			else
  29.138-				sprint(str, "%.5lux(BRANCH)", v);
  29.139+				snprint(str, sizeof str, "%.5lux(BRANCH)", v);
  29.140 		} else
  29.141 			if(a->sym != S)
  29.142-				sprint(str, "%s+%ld(APC)", a->sym->name, a->offset);
  29.143+				snprint(str, sizeof str, "%s+%ld(APC)", a->sym->name, a->offset);
  29.144 			else
  29.145-				sprint(str, "%ld(APC)", a->offset);
  29.146+				snprint(str, sizeof str, "%ld(APC)", a->offset);
  29.147 		break;
  29.148 
  29.149 	case D_FCONST:
  29.150-		sprint(str, "$%e", ieeedtod(a->ieee));
  29.151+		snprint(str, sizeof str, "$%e", ieeedtod(a->ieee));
  29.152 		break;
  29.153 
  29.154 	case D_SCONST:
  29.155-		sprint(str, "$\"%S\"", a->sval);
  29.156+		snprint(str, sizeof str, "$\"%S\"", a->sval);
  29.157 		break;
  29.158 	}
  29.159 	return fmtstrcpy(fp, str);
  29.160@@ -175,39 +174,39 @@ Nconv(Fmt *fp)
  29.161 	s = a->sym;
  29.162 	switch(a->name) {
  29.163 	default:
  29.164-		sprint(str, "GOK-name(%d)", a->name);
  29.165+		snprint(str, sizeof str, "GOK-name(%d)", a->name);
  29.166 		break;
  29.167 
  29.168 	case D_NONE:
  29.169-		sprint(str, "%ld", a->offset);
  29.170+		snprint(str, sizeof str, "%ld", a->offset);
  29.171 		break;
  29.172 
  29.173 	case D_EXTERN:
  29.174 		if(s == S)
  29.175-			sprint(str, "%ld(SB)", a->offset);
  29.176+			snprint(str, sizeof str, "%ld(SB)", a->offset);
  29.177 		else
  29.178-			sprint(str, "%s+%ld(SB)", s->name, a->offset);
  29.179+			snprint(str, sizeof str, "%s+%ld(SB)", s->name, a->offset);
  29.180 		break;
  29.181 
  29.182 	case D_STATIC:
  29.183 		if(s == S)
  29.184-			sprint(str, "<>+%ld(SB)", a->offset);
  29.185+			snprint(str, sizeof str, "<>+%ld(SB)", a->offset);
  29.186 		else
  29.187-			sprint(str, "%s<>+%ld(SB)", s->name, a->offset);
  29.188+			snprint(str, sizeof str, "%s<>+%ld(SB)", s->name, a->offset);
  29.189 		break;
  29.190 
  29.191 	case D_AUTO:
  29.192 		if(s == S)
  29.193-			sprint(str, "%ld(SP)", a->offset);
  29.194+			snprint(str, sizeof str, "%ld(SP)", a->offset);
  29.195 		else
  29.196-			sprint(str, "%s-%ld(SP)", s->name, -a->offset);
  29.197+			snprint(str, sizeof str, "%s-%ld(SP)", s->name, -a->offset);
  29.198 		break;
  29.199 
  29.200 	case D_PARAM:
  29.201 		if(s == S)
  29.202-			sprint(str, "%ld(FP)", a->offset);
  29.203+			snprint(str, sizeof str, "%ld(FP)", a->offset);
  29.204 		else
  29.205-			sprint(str, "%s+%ld(FP)", s->name, a->offset);
  29.206+			snprint(str, sizeof str, "%s+%ld(FP)", s->name, a->offset);
  29.207 		break;
  29.208 	}
  29.209 
    30.1--- a/sys/src/cmd/vl/obj.c
    30.2+++ b/sys/src/cmd/vl/obj.c
    30.3@@ -294,11 +294,9 @@ objfile(char *file)
    30.4 
    30.5 	if(file[0] == '-' && file[1] == 'l') {
    30.6 		if(debug['9'])
    30.7-			sprint(name, "/%s/lib/lib", thestring);
    30.8+			snprint(name, sizeof name, "/%s/lib/lib%s.a", thestring, file+2);
    30.9 		else
   30.10-			sprint(name, "/usr/%clib/lib", thechar);
   30.11-		strcat(name, file+2);
   30.12-		strcat(name, ".a");
   30.13+			snprint(name, sizeof name, "/usr/%clib/lib%s.a", thechar, file+2);
   30.14 		file = name;
   30.15 	}
   30.16 	if(debug['v'])
   30.17@@ -358,7 +356,7 @@ objfile(char *file)
   30.18 			s = lookup(e+5, 0);
   30.19 			if(s->type != SXREF)
   30.20 				continue;
   30.21-			sprint(pname, "%s(%s)", file, s->name);
   30.22+			snprint(pname, sizeof pname, "%s(%s)", file, s->name);
   30.23 			if(debug['v'])
   30.24 				Bprint(&bso, "%5.2f library: %s\n", cputime(), pname);
   30.25 			Bflush(&bso);
   30.26@@ -505,17 +503,17 @@ addlib(char *obj)
   30.27 		return;
   30.28 
   30.29 	if(histfrog[0]->name[1] == '/') {
   30.30-		sprint(name, "");
   30.31+		name[0] = 0;
   30.32 		i = 1;
   30.33 	} else
   30.34 	if(histfrog[0]->name[1] == '.') {
   30.35-		sprint(name, ".");
   30.36+		snprint(name, sizeof name, ".");
   30.37 		i = 0;
   30.38 	} else {
   30.39 		if(debug['9'])
   30.40-			sprint(name, "/%s/lib", thestring);
   30.41+			snprint(name, sizeof name, "/%s/lib", thestring);
   30.42 		else
   30.43-			sprint(name, "/usr/%clib", thechar);
   30.44+			snprint(name, sizeof name, "/usr/%clib", thechar);
   30.45 		i = 0;
   30.46 	}
   30.47 
   30.48@@ -933,7 +931,7 @@ loop:
   30.49 
   30.50 		if(p->from.type == D_FCONST) {
   30.51 			/* size sb 9 max */
   30.52-			sprint(literal, "$%lux", ieeedtof(p->from.ieee));
   30.53+			snprint(literal, sizeof literal, "$%lux", ieeedtof(p->from.ieee));
   30.54 			s = lookup(literal, 0);
   30.55 			if(s->type == 0) {
   30.56 				s->type = SBSS;
   30.57@@ -962,7 +960,7 @@ loop:
   30.58 
   30.59 		if(p->from.type == D_FCONST) {
   30.60 			/* size sb 18 max */
   30.61-			sprint(literal, "$%lux.%lux",
   30.62+			snprint(literal, sizeof literal, "$%lux.%lux",
   30.63 				p->from.ieee->l, p->from.ieee->h);
   30.64 			s = lookup(literal, 0);
   30.65 			if(s->type == 0) {
    31.1--- a/sys/src/cmd/vl/pass.c
    31.2+++ b/sys/src/cmd/vl/pass.c
    31.3@@ -133,9 +133,9 @@ dodata(void)
    31.4 				continue;
    31.5 			/* size should be 19 max */
    31.6 			if(strlen(s->name) >= 10)	/* has loader address */ 
    31.7-				sprint(literal, "$%p.%lux", s, p->from.offset);
    31.8+				snprint(literal, sizeof literal, "$%p.%lux", s, p->from.offset);
    31.9 			else
   31.10-				sprint(literal, "$%s.%d.%lux", s->name, s->version, p->from.offset);
   31.11+				snprint(literal, sizeof literal, "$%s.%d.%lux", s->name, s->version, p->from.offset);
   31.12 		} else {
   31.13 			if(p->from.name != D_NONE)
   31.14 				continue;
   31.15@@ -147,7 +147,7 @@ dodata(void)
   31.16 			if(!(v & 0xffff))
   31.17 				continue;
   31.18 			/* size should be 9 max */
   31.19-			sprint(literal, "$%lux", v);
   31.20+			snprint(literal, sizeof literal, "$%lux", v);
   31.21 		}
   31.22 		s = lookup(literal, 0);
   31.23 		if(s->type == 0) {