// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "runtime.h"
#include "malloc.h"

static uintptr isclosureentry(uintptr);
void runtime·deferproc(void);
void runtime·newproc(void);
void runtime·newstack(void);
void runtime·morestack(void);

// This code is also used for the 386 tracebacks.
// Use uintptr for an appropriate word-sized integer.

// Generic traceback.  Handles runtime stack prints (pcbuf == nil)
// as well as the runtime.Callers function (pcbuf != nil).
// A little clunky to merge the two but avoids duplicating
// the code and all its subtlety.
static int32
gentraceback(byte *pc0, byte *sp, G *g, int32 skip, uintptr *pcbuf, int32 max)
{
	byte *p;
	int32 i, n, iter, sawnewstack;
	uintptr pc, lr, tracepc;
	byte *fp;
	Stktop *stk;
	Func *f;

	pc = (uintptr)pc0;
	lr = 0;
	fp = nil;
	
	// If the PC is goexit, the goroutine hasn't started yet.
	if(pc0 == g->sched.pc && sp == g->sched.sp && pc0 == (byte*)runtime·goexit) {
		fp = sp;
		lr = pc;
		pc = (uintptr)g->entry;
	}
	
	// If the PC is zero, it's likely a nil function call.
	// Start in the caller's frame.
	if(pc == 0) {
		pc = lr;
		lr = 0;
	}

	// If the PC is zero, it's likely a nil function call.
	// Start in the caller's frame.
	if(pc == 0) {
		pc = *(uintptr*)sp;
		sp += sizeof(uintptr);
	}

	n = 0;
	sawnewstack = 0;
	stk = (Stktop*)g->stackbase;
	for(iter = 0; iter < 100 && n < max; iter++) {	// iter avoids looping forever
		// Typically:
		//	pc is the PC of the running function.
		//	sp is the stack pointer at that program counter.
		//	fp is the frame pointer (caller's stack pointer) at that program counter, or nil if unknown.
		//	stk is the stack containing sp.
		//	The caller's program counter is lr, unless lr is zero, in which case it is *(uintptr*)sp.
	
		if(pc == (uintptr)runtime·lessstack) {
			// Hit top of stack segment.  Unwind to next segment.
			pc = (uintptr)stk->gobuf.pc;
			sp = stk->gobuf.sp;
			lr = 0;
			fp = nil;
			if(pcbuf == nil)
				runtime·printf("----- stack segment boundary -----\n");
			stk = (Stktop*)stk->stackbase;
			continue;
		}
		if(pc <= 0x1000 || (f = runtime·findfunc(pc)) == nil) {
			// Dangerous, but worthwhile: see if this is a closure:
			//	ADDQ $wwxxyyzz, SP; RET
			//	[48] 81 c4 zz yy xx ww c3
			// The 0x48 byte is only on amd64.
			p = (byte*)pc;
			// We check p < p+8 to avoid wrapping and faulting if we lose track.
			if(runtime·mheap.arena_start < p && p < p+8 && p+8 < runtime·mheap.arena_used &&  // pointer in allocated memory
			   (sizeof(uintptr) != 8 || *p++ == 0x48) &&  // skip 0x48 byte on amd64
			   p[0] == 0x81 && p[1] == 0xc4 && p[6] == 0xc3) {
				sp += *(uint32*)(p+2);
				pc = *(uintptr*)sp;
				sp += sizeof(uintptr);
				lr = 0;
				fp = nil;
				continue;
			}
			
			// Closure at top of stack, not yet started.
			if(lr == (uintptr)runtime·goexit && (pc = isclosureentry(pc)) != 0) {
				fp = sp;
				continue;
			}

			// Unknown pc: stop.
			break;
		}

		// Found an actual function.
		if(fp == nil) {
			fp = sp;
			if(pc > f->entry && f->frame >= sizeof(uintptr))
				fp += f->frame - sizeof(uintptr);
			if(lr == 0)
				lr = *(uintptr*)fp;
			fp += sizeof(uintptr);
		} else if(lr == 0)
			lr = *(uintptr*)fp;

		if(skip > 0)
			skip--;
		else if(pcbuf != nil)
			pcbuf[n++] = pc;
		else {
			// Print during crash.
			//	main+0xf /home/rsc/go/src/runtime/x.go:23
			//		main(0x1, 0x2, 0x3)
			runtime·printf("%S", f->name);
			if(pc > f->entry)
				runtime·printf("+%p", (uintptr)(pc - f->entry));
			tracepc = pc;	// back up to CALL instruction for funcline.
			if(n > 0 && pc > f->entry)
				tracepc--;
			runtime·printf(" %S:%d\n", f->src, runtime·funcline(f, tracepc));
			runtime·printf("\t%S(", f->name);
			for(i = 0; i < f->args; i++) {
				if(i != 0)
					runtime·prints(", ");
				runtime·printhex(((uintptr*)fp)[i]);
				if(i >= 4) {
					runtime·prints(", ...");
					break;
				}
			}
			runtime·prints(")\n");
			n++;
		}
		
		if(f->entry == (uintptr)runtime·deferproc || f->entry == (uintptr)runtime·newproc)
			fp += 2*sizeof(uintptr);

		if(f->entry == (uintptr)runtime·newstack)
			sawnewstack = 1;

		if(pcbuf == nil && f->entry == (uintptr)runtime·morestack && g == m->g0 && sawnewstack) {
			// The fact that we saw newstack means that morestack
			// has managed to record its information in m, so we can
			// use it to keep unwinding the stack.
			runtime·printf("----- morestack called from goroutine %d -----\n", m->curg->goid);
			pc = (uintptr)m->morepc;
			sp = m->morebuf.sp - sizeof(void*);
			lr = (uintptr)m->morebuf.pc;
			fp = m->morebuf.sp;
			sawnewstack = 0;
			g = m->curg;
			stk = (Stktop*)g->stackbase;
			continue;
		}

		if(pcbuf == nil && f->entry == (uintptr)runtime·lessstack && g == m->g0) {
			// Lessstack is running on scheduler stack.  Switch to original goroutine.
			runtime·printf("----- lessstack called from goroutine %d -----\n", m->curg->goid);
			g = m->curg;
			stk = (Stktop*)g->stackbase;
			sp = stk->gobuf.sp;
			pc = (uintptr)stk->gobuf.pc;
			fp = nil;
			lr = 0;
			continue;
		}

		// Unwind to next frame.
		pc = lr;
		lr = 0;
		sp = fp;
		fp = nil;
	}
	
	if(pcbuf == nil && (pc = g->gopc) != 0 && (f = runtime·findfunc(pc)) != nil) {
		runtime·printf("----- goroutine created by -----\n%S", f->name);
		if(pc > f->entry)
			runtime·printf("+%p", (uintptr)(pc - f->entry));
		tracepc = pc;	// back up to CALL instruction for funcline.
		if(n > 0 && pc > f->entry)
			tracepc--;
		runtime·printf(" %S:%d\n", f->src, runtime·funcline(f, tracepc));
	}
		
	return n;
}

void
runtime·traceback(byte *pc0, byte *sp, byte*, G *g)
{
	gentraceback(pc0, sp, g, 0, nil, 100);
}

int32
runtime·callers(int32 skip, uintptr *pcbuf, int32 m)
{
	byte *pc, *sp;

	// our caller's pc, sp.
	sp = (byte*)&skip;
	pc = runtime·getcallerpc(&skip);

	return gentraceback(pc, sp, g, skip, pcbuf, m);
}

static uintptr
isclosureentry(uintptr pc)
{
	byte *p;
	int32 i, siz;
	
	p = (byte*)pc;
	if(p < runtime·mheap.arena_start || p+32 > runtime·mheap.arena_used)
		return 0;

	if(*p == 0xe8) {
		// CALL fn
		return pc+5+*(int32*)(p+1);
	}
	
	if(sizeof(uintptr) == 8 && p[0] == 0x48 && p[1] == 0xb9 && p[10] == 0xff && p[11] == 0xd1) {
		// MOVQ $fn, CX; CALL *CX
		return *(uintptr*)(p+2);
	}

	// SUBQ $siz, SP
	if((sizeof(uintptr) == 8 && *p++ != 0x48) || *p++ != 0x81 || *p++ != 0xec)
		return 0;
	siz = *(uint32*)p;
	p += 4;
	
	// MOVQ $q, SI
	if((sizeof(uintptr) == 8 && *p++ != 0x48) || *p++ != 0xbe)
		return 0;
	p += sizeof(uintptr);

	// MOVQ SP, DI
	if((sizeof(uintptr) == 8 && *p++ != 0x48) || *p++ != 0x89 || *p++ != 0xe7)
		return 0;

	// CLD on 32-bit
	if(sizeof(uintptr) == 4 && *p++ != 0xfc)
		return 0;

	if(siz <= 4*sizeof(uintptr)) {
		// MOVSQ...
		for(i=0; i<siz; i+=sizeof(uintptr))
			if((sizeof(uintptr) == 8 && *p++ != 0x48) || *p++ != 0xa5)
				return 0;
	} else {
		// MOVQ $(siz/8), CX  [32-bit immediate siz/8]
		if((sizeof(uintptr) == 8 && *p++ != 0x48) || *p++ != 0xc7 || *p++ != 0xc1)
			return 0;
		p += 4;
		
		// REP MOVSQ
		if(*p++ != 0xf3 || (sizeof(uintptr) == 8 && *p++ != 0x48) || *p++ != 0xa5)
			return 0;
	}
	
	// CALL fn
	if(*p == 0xe8) {
		p++;
		return (uintptr)p+4 + *(int32*)p;
	}
	
	// MOVQ $fn, CX; CALL *CX
	if(sizeof(uintptr) != 8 || *p++ != 0x48 || *p++ != 0xb9)
		return 0;

	pc = *(uintptr*)p;
	p += 8;
	
	if(*p++ != 0xff || *p != 0xd1)
		return 0;

	return pc;
}
