1
0
mirror of https://github.com/golang/go synced 2024-11-22 03:34:40 -07:00

runtime: make printf work on misaligned stack

(Shouldn't happen, but if it does, it's useful to be
able to use printf to debug it.)

R=r
CC=golang-dev
https://golang.org/cl/4250057
This commit is contained in:
Russ Cox 2011-03-04 15:42:39 -05:00
parent c91daefb24
commit e339d27db7

View File

@ -42,113 +42,108 @@ runtime·printf(int8 *s, ...)
vprintf(s, arg); vprintf(s, arg);
} }
static byte*
vrnd(byte *p, int32 x)
{
if((uint32)(uintptr)p&(x-1))
p += x - ((uint32)(uintptr)p&(x-1));
return p;
}
// Very simple printf. Only for debugging prints. // Very simple printf. Only for debugging prints.
// Do not add to this without checking with Rob. // Do not add to this without checking with Rob.
static void static void
vprintf(int8 *s, byte *arg) vprintf(int8 *s, byte *base)
{ {
int8 *p, *lp; int8 *p, *lp;
byte *narg; uintptr arg, narg;
byte *v;
// lock(&debuglock); // lock(&debuglock);
lp = p = s; lp = p = s;
arg = 0;
for(; *p; p++) { for(; *p; p++) {
if(*p != '%') if(*p != '%')
continue; continue;
if(p > lp) if(p > lp)
runtime·write(2, lp, p-lp); runtime·write(2, lp, p-lp);
p++; p++;
narg = nil; narg = 0;
switch(*p) { switch(*p) {
case 't': case 't':
narg = arg + 1; narg = arg + 1;
break; break;
case 'd': // 32-bit case 'd': // 32-bit
case 'x': case 'x':
arg = vrnd(arg, 4); arg = runtime·rnd(arg, 4);
narg = arg + 4; narg = arg + 4;
break; break;
case 'D': // 64-bit case 'D': // 64-bit
case 'U': case 'U':
case 'X': case 'X':
case 'f': case 'f':
arg = vrnd(arg, sizeof(uintptr)); arg = runtime·rnd(arg, sizeof(uintptr));
narg = arg + 8; narg = arg + 8;
break; break;
case 'C': case 'C':
arg = vrnd(arg, sizeof(uintptr)); arg = runtime·rnd(arg, sizeof(uintptr));
narg = arg + 16; narg = arg + 16;
break; break;
case 'p': // pointer-sized case 'p': // pointer-sized
case 's': case 's':
arg = vrnd(arg, sizeof(uintptr)); arg = runtime·rnd(arg, sizeof(uintptr));
narg = arg + sizeof(uintptr); narg = arg + sizeof(uintptr);
break; break;
case 'S': // pointer-aligned but bigger case 'S': // pointer-aligned but bigger
arg = vrnd(arg, sizeof(uintptr)); arg = runtime·rnd(arg, sizeof(uintptr));
narg = arg + sizeof(String); narg = arg + sizeof(String);
break; break;
case 'a': // pointer-aligned but bigger case 'a': // pointer-aligned but bigger
arg = vrnd(arg, sizeof(uintptr)); arg = runtime·rnd(arg, sizeof(uintptr));
narg = arg + sizeof(Slice); narg = arg + sizeof(Slice);
break; break;
case 'i': // pointer-aligned but bigger case 'i': // pointer-aligned but bigger
case 'e': case 'e':
arg = vrnd(arg, sizeof(uintptr)); arg = runtime·rnd(arg, sizeof(uintptr));
narg = arg + sizeof(Eface); narg = arg + sizeof(Eface);
break; break;
} }
v = base+arg;
switch(*p) { switch(*p) {
case 'a': case 'a':
runtime·printslice(*(Slice*)arg); runtime·printslice(*(Slice*)v);
break; break;
case 'd': case 'd':
runtime·printint(*(int32*)arg); runtime·printint(*(int32*)v);
break; break;
case 'D': case 'D':
runtime·printint(*(int64*)arg); runtime·printint(*(int64*)v);
break; break;
case 'e': case 'e':
runtime·printeface(*(Eface*)arg); runtime·printeface(*(Eface*)v);
break; break;
case 'f': case 'f':
runtime·printfloat(*(float64*)arg); runtime·printfloat(*(float64*)v);
break; break;
case 'C': case 'C':
runtime·printcomplex(*(Complex128*)arg); runtime·printcomplex(*(Complex128*)v);
break; break;
case 'i': case 'i':
runtime·printiface(*(Iface*)arg); runtime·printiface(*(Iface*)v);
break; break;
case 'p': case 'p':
runtime·printpointer(*(void**)arg); runtime·printpointer(*(void**)v);
break; break;
case 's': case 's':
runtime·prints(*(int8**)arg); runtime·prints(*(int8**)v);
break; break;
case 'S': case 'S':
runtime·printstring(*(String*)arg); runtime·printstring(*(String*)v);
break; break;
case 't': case 't':
runtime·printbool(*(bool*)arg); runtime·printbool(*(bool*)v);
break; break;
case 'U': case 'U':
runtime·printuint(*(uint64*)arg); runtime·printuint(*(uint64*)v);
break; break;
case 'x': case 'x':
runtime·printhex(*(uint32*)arg); runtime·printhex(*(uint32*)v);
break; break;
case 'X': case 'X':
runtime·printhex(*(uint64*)arg); runtime·printhex(*(uint64*)v);
break; break;
} }
arg = narg; arg = narg;