Commit 3aa063d7 authored by Russ Cox's avatar Russ Cox

delete stack mark strings

in favor of using in-memory copy of symbol table.

$ ls -l pretty pretty.big
-rwxr-xr-x  1 rsc  eng  439516 Nov 21 16:43 pretty
-rwxr-xr-x  1 rsc  eng  580984 Nov 21 16:20 pretty.big
$

R=r
DELTA=446  (238 added, 178 deleted, 30 changed)
OCL=19851
CL=19884
parent ffafad19
......@@ -33,7 +33,6 @@
#define NOPROF (1<<0)
#define DUPOK (1<<1)
#define NOSPLIT (1<<2)
#define SOFmark "\xa7\xf1\xd9\x2a\x82\xc8\xd8\xfe"
/*
* amd64
......
......@@ -402,7 +402,6 @@ main(int argc, char *argv[])
doprof1();
else
doprof2();
addstackmark();
span();
doinit();
asmb();
......
......@@ -293,100 +293,6 @@ byteq(int v)
return p;
}
void
markstk(Prog *l)
{
Prog *p0, *p, *q, *r;
int32 i, n, line;
Sym *s;
version++;
s = lookup(l->from.sym->name, version);
s->type = STEXT;
line = l->line;
// start with fake copy of ATEXT
p0 = prg();
p = p0;
*p = *l; // note this gets p->pcond and p->line
p->from.type = D_STATIC;
p->from.sym = s;
p->to.offset = 0;
// put out magic sequence
n = strlen(SOFmark);
for(i=0; i<n; i++) {
q = byteq(SOFmark[i]);
q->line = line;
p->link = q;
p = q;
}
// put out stack offset
n = l->to.offset;
if(n < 0)
n = 0;
for(i=0; i<3; i++) {
q = byteq(n);
q->line = line;
p->link = q;
p = q;
n = n>>8;
}
// put out null terminated name
for(i=0;; i++) {
n = s->name[i];
q = byteq(n);
q->line = line;
p->link = q;
p = q;
if(n == 0)
break;
}
// put out return instruction
q = prg();
q->as = ARET;
q->line = line;
p->link = q;
p = q;
r = l->pcond;
l->pcond = p0;
p->link = r;
p0->pcond = r;
// hard part is linking end of
// the text body to my fake ATEXT
for(p=l;; p=q) {
q = p->link;
if(q == r) {
p->link = p0;
return;
}
}
}
void
addstackmark(void)
{
Prog *p;
if(debug['v'])
Bprint(&bso, "%5.2f stkmark\n", cputime());
Bflush(&bso);
for(p=textp; p!=P; p=p->pcond) {
markstk(p); // splice in new body
p = p->pcond; // skip the one we just put in
}
// for(p=textp; p!=P; p=p->pcond)
// print("%P\n", p);
}
int
relinv(int a)
{
......
......@@ -26,6 +26,7 @@ LIBOFILES=\
rune.$O\
proc.$O\
string.$O\
symtab.$O\
sys_file.$O\
OFILES=$(RT0OFILES) $(LIBOFILES)
......@@ -61,3 +62,4 @@ sys_file.$O: sys_file.c sys_types.h $(OS_H)
runtime.acid: runtime.h proc.c
$(CC) -a proc.c >runtime.acid
......@@ -420,21 +420,12 @@ sys·printinter(Map *im, void *it)
void
sys·reflect(Map *im, void *it, uint64 retit, string rettype)
{
string s;
int32 n;
byte *type;
if(im == nil) {
retit = 0;
rettype = nil;
} else {
retit = (uint64)it;
type = im->sigt->name;
n = findnull((int8*)type);
s = mal(sizeof *s + n + 1);
s->len = n;
mcpy(s->str, type, n);
rettype = s;
rettype = gostring(im->sigt->name);
}
FLUSH(&retit);
FLUSH(&rettype);
......
......@@ -25,7 +25,7 @@ dump(byte *p, int32 n)
void
prints(int8 *s)
{
sys·write(1, s, findnull(s));
sys·write(1, s, findnull((byte*)s));
}
void
......
......@@ -6,8 +6,6 @@
extern int32 debug;
static int8 spmark[] = "\xa7\xf1\xd9\x2a\x82\xc8\xd8\xfe";
extern uint8 end;
void
......@@ -18,7 +16,8 @@ traceback(uint8 *pc, uint8 *sp, void* r15)
uint8* callpc;
int32 counter;
int32 i;
int8* name;
string name;
Func *f;
G g;
Stktop *stktop;
......@@ -33,7 +32,7 @@ traceback(uint8 *pc, uint8 *sp, void* r15)
}
counter = 0;
name = "panic";
name = gostring((byte*)"panic");
for(;;){
callpc = pc;
if((uint8*)retfromnewstack == pc) {
......@@ -46,21 +45,11 @@ traceback(uint8 *pc, uint8 *sp, void* r15)
sp += 16; // two irrelevant calls on stack - morestack, plus the call morestack made
continue;
}
/* find SP offset by stepping back through instructions to SP offset marker */
while(pc > (uint8*)0x1000+sizeof spmark-1) {
if(pc >= &end)
return;
for(spp = spmark; *spp != '\0' && *pc++ == (uint8)*spp++; )
;
if(*spp == '\0'){
spoff = *pc++;
spoff += *pc++ << 8;
spoff += *pc++ << 16;
name = (int8*)pc;
sp += spoff + 8;
break;
}
}
f = findfunc((uint64)callpc);
if(f == nil)
return;
name = f->name;
sp += f->frame;
if(counter++ > 100){
prints("stack trace terminated\n");
break;
......@@ -73,7 +62,7 @@ traceback(uint8 *pc, uint8 *sp, void* r15)
sys·printpointer(callpc - 1); // -1 to get to CALL instr.
prints("?zi\n");
prints("\t");
prints(name);
sys·printstring(name);
prints("(");
for(i = 0; i < 3; i++){
if(i != 0)
......@@ -82,7 +71,7 @@ traceback(uint8 *pc, uint8 *sp, void* r15)
}
prints(", ...)\n");
prints("\t");
prints(name);
sys·printstring(name);
prints("(");
for(i = 0; i < 3; i++){
if(i != 0)
......
......@@ -107,6 +107,15 @@ mmov(byte *t, byte *f, uint32 n)
}
}
byte*
mchr(byte *p, byte c, byte *ep)
{
for(; p < ep; p++)
if(*p == c)
return p;
return nil;
}
uint32
rnd(uint32 n, uint32 m)
{
......@@ -464,7 +473,7 @@ getenv(int8 *s)
byte *v, *bs;
bs = (byte*)s;
len = findnull(s);
len = findnull(bs);
for(i=0; i<envc; i++){
v = envv[i];
for(j=0; j<len; j++)
......@@ -509,21 +518,10 @@ sys·envc(int32 v)
void
sys·argv(int32 i, string s)
{
uint8* str;
int32 l;
if(i < 0 || i >= argc) {
if(i >= 0 && i < argc)
s = gostring(argv[i]);
else
s = emptystring;
goto out;
}
str = argv[i];
l = findnull((int8*)str);
s = mal(sizeof(s->len)+l);
s->len = l;
mcpy(s->str, str, l);
out:
FLUSH(&s);
}
......@@ -531,21 +529,10 @@ out:
void
sys·envv(int32 i, string s)
{
uint8* str;
int32 l;
if(i < 0 || i >= envc) {
if(i >= 0 && i < envc)
s = gostring(envv[i]);
else
s = emptystring;
goto out;
}
str = envv[i];
l = findnull((int8*)str);
s = mal(sizeof(s->len)+l);
s->len = l;
mcpy(s->str, str, l);
out:
FLUSH(&s);
}
......@@ -742,33 +729,3 @@ algarray[3] =
{ memhash, memequal, memprint, memcopy }, // 2 - treat pointers as ints
};
// Return a pointer to a byte array containing the symbol table segment.
//
// NOTE(rsc): I expect that we will clean up both the method of getting
// at the symbol table and the exact format of the symbol table at some
// point in the future. It probably needs to be better integrated with
// the type strings table too. This is just a quick way to get started
// and figure out what we want from/can do with it.
void
sys·symdat(Array *symtab, Array *pclntab)
{
Array *a;
int32 *v;
v = (int32*)(0x99LL<<32); /* known to 6l */
a = mal(sizeof *a);
a->nel = v[0];
a->cap = a->nel;
a->array = (byte*)&v[2];
symtab = a;
FLUSH(&symtab);
a = mal(sizeof *a);
a->nel = v[1];
a->cap = a->nel;
a->array = (byte*)&v[2] + v[0];
pclntab = a;
FLUSH(&pclntab);
}
......@@ -19,32 +19,35 @@ typedef uint64 uintptr;
/*
* get rid of C types
* the / / / forces a syntax error immediately,
* which will show "last name: XXunsigned".
*/
#define unsigned XXunsigned
#define signed XXsigned
#define char XXchar
#define short XXshort
#define int XXint
#define long XXlong
#define float XXfloat
#define double XXdouble
#define unsigned XXunsigned / / /
#define signed XXsigned / / /
#define char XXchar / / /
#define short XXshort / / /
#define int XXint / / /
#define long XXlong / / /
#define float XXfloat / / /
#define double XXdouble / / /
/*
* defined types
*/
typedef uint8 bool;
typedef uint8 byte;
typedef struct String *string;
typedef struct Alg Alg;
typedef struct Array Array;
typedef struct Gobuf Gobuf;
typedef struct Func Func;
typedef struct G G;
typedef struct M M;
typedef struct Stktop Stktop;
typedef struct Alg Alg;
typedef struct Gobuf Gobuf;
typedef struct Lock Lock;
typedef union Note Note;
typedef struct M M;
typedef struct Mem Mem;
typedef struct Usema Usema;
typedef union Note Note;
typedef struct Stktop Stktop;
typedef struct String *string;
typedef struct Usema Usema;
/*
* per cpu declaration
......@@ -179,6 +182,18 @@ struct SigTab
int8 *name;
};
// (will be) shared with go; edit ../cmd/6g/sys.go too.
// should move out of sys.go eventually.
// also eventually, the loaded symbol table should
// be closer to this form.
struct Func
{
string name;
string type;
uint64 entry;
int64 frame;
};
/*
* defined macros
* you need super-goru privilege
......@@ -202,7 +217,7 @@ extern int32 maxround;
* common functions and data
*/
int32 strcmp(byte*, byte*);
int32 findnull(int8*);
int32 findnull(byte*);
void dump(byte*, int32);
int32 runetochar(byte*, int32);
int32 chartorune(uint32*, byte*);
......@@ -220,10 +235,12 @@ void* getu(void);
void throw(int8*);
uint32 rnd(uint32, uint32);
void prints(int8*);
byte* mchr(byte*, byte, byte*);
void mcpy(byte*, byte*, uint32);
void mmov(byte*, byte*, uint32);
void* mal(uint32);
uint32 cmpstring(string, string);
string gostring(byte*);
void initsig(void);
int32 gotraceback(void);
void traceback(uint8 *pc, uint8 *sp, G* gp);
......@@ -243,6 +260,7 @@ void sigaltstack(void*, void*);
void signalstack(byte*, int32);
G* malg(int32);
void minit(void);
Func* findfunc(uint64);
/*
* mutual exclusion locks. in the uncontended case,
......
......@@ -8,7 +8,7 @@ static int32 empty = 0;
string emptystring = (string)&empty;
int32
findnull(int8 *s)
findnull(byte *s)
{
int32 l;
......@@ -17,6 +17,19 @@ findnull(int8 *s)
return l;
}
string
gostring(byte *str)
{
int32 l;
string s;
l = findnull(str);
s = mal(sizeof(s->len)+l+1);
s->len = l;
mcpy(s->str, str, l+1);
return s;
}
void
sys·catstring(string s1, string s2, string s3)
{
......
// 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"
// Runtime symbol table access.
// Very much a work in progress.
#define SYMCOUNTS ((int32*)(0x99LL<<32)) // known to 6l
#define SYMDATA ((byte*)(0x99LL<<32) + 8)
// Return a pointer to a byte array containing the symbol table segment.
//
// NOTE(rsc): I expect that we will clean up both the method of getting
// at the symbol table and the exact format of the symbol table at some
// point in the future. It probably needs to be better integrated with
// the type strings table too. This is just a quick way to get started
// and figure out what we want from/can do with it.
void
sys·symdat(Array *symtab, Array *pclntab)
{
Array *a;
int32 *v;
v = SYMCOUNTS;
a = mal(sizeof *a);
a->nel = v[0];
a->cap = a->nel;
a->array = SYMDATA;
symtab = a;
FLUSH(&symtab);
a = mal(sizeof *a);
a->nel = v[1];
a->cap = a->nel;
a->array = SYMDATA + v[0];
pclntab = a;
FLUSH(&pclntab);
}
typedef struct Sym Sym;
struct Sym
{
uint64 value;
byte symtype;
byte *name;
byte *gotype;
};
// Walk over symtab, calling fn(&s) for each symbol.
void
walksymtab(void (*fn)(Sym*))
{
int32 *v;
byte *p, *ep, *q;
Sym s;
v = SYMCOUNTS;
p = SYMDATA;
ep = p + v[0];
while(p < ep) {
if(p + 7 > ep)
break;
s.value = ((uint32)p[0]<<24) | ((uint32)p[1]<<16) | ((uint32)p[2]<<8) | ((uint32)p[3]);
if(!(p[4]&0x80))
break;
s.symtype = p[4] & ~0x80;
p += 5;
if(s.symtype == 'z' || s.symtype == 'Z') {
// path reference string - skip first byte,
// then 2-byte pairs ending at two zeros.
// for now, just skip over it and ignore it.
q = p+1;
for(;;) {
if(q+2 > ep)
return;
if(q[0] == '\0' && q[1] == '\0')
break;
q += 2;
}
p = q+2;
s.name = nil;
}else{
q = mchr(p, '\0', ep);
if(q == nil)
break;
s.name = p;
p = q+1;
}
q = mchr(p, '\0', ep);
if(q == nil)
break;
s.gotype = p;
p = q+1;
fn(&s);
}
}
// Symtab walker; accumulates info about functions.
Func *func;
int32 nfunc;
static void
dofunc(Sym *sym)
{
static byte *lastfuncname;
static Func *lastfunc;
Func *f;
if(lastfunc && sym->symtype == 'm') {
lastfunc->frame = sym->value;
return;
}
if(sym->symtype != 'T' && sym->symtype != 't')
return;
if(strcmp(sym->name, (byte*)"etext") == 0)
return;
if(func == nil) {
nfunc++;
return;
}
f = &func[nfunc++];
f->name = gostring(sym->name);
f->entry = sym->value;
lastfunc = f;
}
static void
buildfuncs(void)
{
extern byte etext[];
if(func != nil)
return;
nfunc = 0;
walksymtab(dofunc);
func = mal((nfunc+1)*sizeof func[0]);
nfunc = 0;
walksymtab(dofunc);
func[nfunc].entry = (uint64)etext;
}
Func*
findfunc(uint64 addr)
{
Func *f;
int32 i, nf, n;
if(func == nil)
buildfuncs();
if(nfunc == 0)
return nil;
if(addr < func[0].entry || addr >= func[nfunc].entry)
return nil;
// linear search, for debugging
if(0) {
for(i=0; i<nfunc; i++) {
if(func[i].entry <= addr && addr < func[i+1].entry)
return &func[i];
}
return nil;
}
// binary search to find func with entry <= addr.
f = func;
nf = nfunc;
while(nf > 0) {
n = nf/2;
if(f[n].entry <= addr && addr < f[n+1].entry)
return &f[n];
else if(addr < f[n].entry)
nf = n;
else {
f += n+1;
nf -= n+1;
}
}
// can't get here -- we already checked above
// that the address was in the table bounds.
// this can only happen if the table isn't sorted
// by address or if the binary search above is buggy.
prints("findfunc unreachable\n");
return nil;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment