diff options
| author | Russ Cox <rsc@golang.org> | 2013-07-16 09:41:38 -0400 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2013-07-16 09:41:38 -0400 |
| commit | 5d363c6357ebcacc8ba7c24420f7cfd2e530591a (patch) | |
| tree | bc168c1cbd6483edd35aa74cdab1481812cdfc3c /src/pkg/runtime/traceback_arm.c | |
| parent | 63e0ddc7bf0c7523d826331ff51a551c5040b50b (diff) | |
| download | go-5d363c6357ebcacc8ba7c24420f7cfd2e530591a.tar.xz | |
cmd/ld, runtime: new in-memory symbol table format
Design at http://golang.org/s/go12symtab.
This enables some cleanup of the garbage collector metadata
that will be done in future CLs.
This CL does not move the old symtab and pclntab back into
an unmapped section of the file. That's a bit tricky and will be
done separately.
Fixes #4020.
R=golang-dev, dave, cshapiro, iant, r
CC=golang-dev, nigeltao
https://golang.org/cl/11085043
Diffstat (limited to 'src/pkg/runtime/traceback_arm.c')
| -rw-r--r-- | src/pkg/runtime/traceback_arm.c | 41 |
1 files changed, 18 insertions, 23 deletions
diff --git a/src/pkg/runtime/traceback_arm.c b/src/pkg/runtime/traceback_arm.c index 599f6093eb..e5a475f80f 100644 --- a/src/pkg/runtime/traceback_arm.c +++ b/src/pkg/runtime/traceback_arm.c @@ -15,15 +15,18 @@ void _mod(void); void _divu(void); void _modu(void); +static String unknown = { (uint8*)"?", 1 }; + int32 runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip, uintptr *pcbuf, int32 max, void (*callback)(Stkframe*, void*), void *v, bool printall) { - int32 i, n, nprint, skip0; + int32 i, n, nprint, skip0, line; uintptr x, tracepc; bool waspanic, printing; Func *f, *f2; Stkframe frame; Stktop *stk; + String file; skip0 = skip; @@ -76,11 +79,8 @@ runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip, // Derive frame pointer and link register. if(frame.lr == 0) frame.lr = *(uintptr*)frame.sp; - if(frame.fp == 0) { - frame.fp = frame.sp; - if(frame.pc > f->entry && f->frame >= sizeof(uintptr)) - frame.fp += f->frame; - } + if(frame.fp == 0) + frame.fp = frame.sp + runtime·funcspdelta(f, frame.pc); // Derive size of arguments. frame.argp = (byte*)frame.fp + sizeof(uintptr); @@ -96,7 +96,7 @@ runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip, else if((f2 = runtime·findfunc(frame.lr)) != nil && f2->frame >= sizeof(uintptr)) frame.arglen = f2->frame; // conservative overestimate else { - runtime·printf("runtime: unknown argument frame size for %S\n", f->name); + runtime·printf("runtime: unknown argument frame size for %S\n", *f->name); if(!printing) runtime·throw("invalid stack"); } @@ -113,7 +113,7 @@ runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip, frame.varlen = frame.fp - frame.sp; } else { if(f->locals > frame.fp - frame.sp) { - runtime·printf("runtime: inconsistent locals=%p frame=%p fp=%p sp=%p for %S\n", (uintptr)f->locals, (uintptr)f->frame, frame.fp, frame.sp, f->name); + runtime·printf("runtime: inconsistent locals=%p frame=%p fp=%p sp=%p for %S\n", (uintptr)f->locals, (uintptr)f->frame, frame.fp, frame.sp, *f->name); runtime·throw("invalid stack"); } frame.varp = (byte*)frame.fp - f->locals; @@ -138,7 +138,7 @@ runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip, tracepc = frame.pc; // back up to CALL instruction for funcline. if(n > 0 && frame.pc > f->entry && !waspanic) tracepc -= sizeof(uintptr); - runtime·printf("%S(", f->name); + runtime·printf("%S(", *f->name); for(i = 0; i < frame.arglen/sizeof(uintptr); i++) { if(i >= 5) { runtime·prints(", ..."); @@ -149,7 +149,8 @@ runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip, runtime·printhex(((uintptr*)frame.argp)[i]); } runtime·prints(")\n"); - runtime·printf("\t%S:%d", f->src, runtime·funcline(f, tracepc)); + line = runtime·funcline(f, tracepc, &file); + runtime·printf("\t%S:%d", file, line); if(frame.pc > f->entry) runtime·printf(" +%p", (uintptr)(frame.pc - f->entry)); if(m->throwing && gp == m->curg) @@ -164,7 +165,7 @@ runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip, waspanic = f->entry == (uintptr)runtime·sigpanic; // Do not unwind past the bottom of the stack. - if(f->entry == (uintptr)runtime·goexit || f->entry == (uintptr)runtime·mstart || f->entry == (uintptr)_rt0_go) + if(f->entry == (uintptr)runtime·goexit || f->entry == (uintptr)runtime·mstart || f->entry == (uintptr)runtime·mcall || f->entry == (uintptr)_rt0_go) break; // Unwind to next frame. @@ -172,16 +173,7 @@ runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip, frame.lr = 0; frame.sp = frame.fp; frame.fp = 0; - - // If this was div or divu or mod or modu, the caller had - // an extra 8 bytes on its stack. Adjust sp. - if(f->entry == (uintptr)_div || f->entry == (uintptr)_divu || f->entry == (uintptr)_mod || f->entry == (uintptr)_modu) - frame.sp += 8; - - // If this was deferproc or newproc, the caller had an extra 12. - if(f->entry == (uintptr)runtime·deferproc || f->entry == (uintptr)runtime·newproc) - frame.sp += 12; - + // sighandler saves the lr on stack before faking a call to sigpanic if(waspanic) { x = *(uintptr*)frame.sp; @@ -203,16 +195,19 @@ runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip, static void printcreatedby(G *gp) { + int32 line; uintptr pc, tracepc; Func *f; + String file; if((pc = gp->gopc) != 0 && (f = runtime·findfunc(pc)) != nil && runtime·showframe(f, gp) && gp->goid != 1) { - runtime·printf("created by %S\n", f->name); + runtime·printf("created by %S\n", *f->name); tracepc = pc; // back up to CALL instruction for funcline. if(pc > f->entry) tracepc -= sizeof(uintptr); - runtime·printf("\t%S:%d", f->src, runtime·funcline(f, tracepc)); + line = runtime·funcline(f, tracepc, &file); + runtime·printf("\t%S:%d", file, line); if(pc > f->entry) runtime·printf(" +%p", (uintptr)(pc - f->entry)); runtime·printf("\n"); |
