diff options
Diffstat (limited to 'src/cmd/godefs/stabs.c')
-rw-r--r-- | src/cmd/godefs/stabs.c | 456 |
1 files changed, 0 insertions, 456 deletions
diff --git a/src/cmd/godefs/stabs.c b/src/cmd/godefs/stabs.c deleted file mode 100644 index 2c3d431b8..000000000 --- a/src/cmd/godefs/stabs.c +++ /dev/null @@ -1,456 +0,0 @@ -// 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. - -// Parse stabs debug info. - -#include "a.h" - -int stabsdebug = 1; - -// Hash table for type lookup by number. -Type *hash[1024]; - -// Look up type by number pair. -// TODO(rsc): Iant points out that n1 and n2 are always small and dense, -// so an array of arrays would be a better representation. -Type* -typebynum(uint n1, uint n2) -{ - uint h; - Type *t; - - h = (n1*53+n2) % nelem(hash); - for(t=hash[h]; t; t=t->next) - if(t->n1 == n1 && t->n2 == n2) - return t; - t = emalloc(sizeof *t); - t->next = hash[h]; - hash[h] = t; - t->n1 = n1; - t->n2 = n2; - return t; -} - -// Parse name and colon from *pp, leaving copy in *sp. -static int -parsename(char **pp, char **sp) -{ - char *p; - char *s; - - p = *pp; - while(*p != '\0' && *p != ':') - p++; - if(*p == '\0') { - fprint(2, "parsename expected colon\n"); - return -1; - } - s = emalloc(p - *pp + 1); - memmove(s, *pp, p - *pp); - *sp = s; - *pp = p+1; - return 0; -} - -// Parse single number from *pp. -static int -parsenum1(char **pp, vlong *np) -{ - char *p; - - p = *pp; - if(*p != '-' && (*p < '0' || *p > '9')) { - fprint(2, "parsenum expected minus or digit\n"); - return -1; - } - *np = strtoll(p, pp, 10); - return 0; -} - -// Parse type number - either single number or (n1, n2). -static int -parsetypenum(char **pp, vlong *n1p, vlong *n2p) -{ - char *p; - - p = *pp; - if(*p == '(') { - p++; - if(parsenum1(&p, n1p) < 0) - return -1; - if(*p++ != ',') { - if(stabsdebug) - fprint(2, "parsetypenum expected comma\n"); - return -1; - } - if(parsenum1(&p, n2p) < 0) - return -1; - if(*p++ != ')') { - if(stabsdebug) - fprint(2, "parsetypenum expected right paren\n"); - return -1; - } - *pp = p; - return 0; - } - - if(parsenum1(&p, n1p) < 0) - return -1; - *n2p = 0; - *pp = p; - return 0; -} - -// Written to parse max/min of vlong correctly. -static vlong -parseoctal(char **pp) -{ - char *p; - vlong n; - - p = *pp; - if(*p++ != '0') - return 0; - n = 0; - while(*p >= '0' && *p <= '9') - n = n << 3 | *p++ - '0'; - *pp = p; - return n; -} - -// Integer types are represented in stabs as a "range" -// type with a lo and a hi value. The lo and hi used to -// be lo and hi for the type, but there are now odd -// extensions for floating point and 64-bit numbers. -// -// Have to keep signs separate from values because -// Int64's lo is -0. -typedef struct Intrange Intrange; -struct Intrange -{ - vlong lo; - vlong hi; - int kind; -}; - -Intrange intranges[] = { - 0, 127, Int8, // char - -128, 127, Int8, // signed char - 0, 255, Uint8, - -32768, 32767, Int16, - 0, 65535, Uint16, - -2147483648LL, 2147483647LL, Int32, - 0, 4294967295LL, Uint32, - 1LL << 63, ~(1LL << 63), Int64, - 0, -1, Uint64, - 4, 0, Float32, - 8, 0, Float64, - 16, 0, Void, -}; - -int kindsize[] = { - 0, - 0, - 8, - 8, - 16, - 16, - 32, - 32, - 64, - 64, -}; - -// Parse a single type definition from *pp. -static Type* -parsedef(char **pp, char *name) -{ - char *p; - Type *t, *tt; - int i; - vlong n1, n2, lo, hi; - Field *f; - Intrange *r; - - p = *pp; - - // reference to another type? - if(isdigit(*p) || *p == '(') { - if(parsetypenum(&p, &n1, &n2) < 0) - return nil; - t = typebynum(n1, n2); - if(name && t->name == nil) { - t->name = name; - // save definitions of names beginning with $ - if(name[0] == '$' && !t->saved) { - typ = erealloc(typ, (ntyp+1)*sizeof typ[0]); - typ[ntyp] = t; - ntyp++; - } - } - - // is there an =def suffix? - if(*p == '=') { - p++; - tt = parsedef(&p, name); - if(tt == nil) - return nil; - - if(tt == t) { - tt->kind = Void; - } else { - t->type = tt; - t->kind = Typedef; - } - - // assign given name, but do not record in typ. - // assume the name came from a typedef - // which will be recorded. - if(name) - tt->name = name; - } - - *pp = p; - return t; - } - - // otherwise a type literal. first letter identifies kind - t = emalloc(sizeof *t); - switch(*p) { - default: - fprint(2, "unknown type char %c in %s\n", *p, p); - *pp = ""; - return t; - - case '@': // type attribute - while (*++p != ';'); - *pp = ++p; - return parsedef(pp, nil); - - case '*': // pointer - p++; - t->kind = Ptr; - tt = parsedef(&p, nil); - if(tt == nil) - return nil; - t->type = tt; - break; - - case 'a': // array - p++; - t->kind = Array; - // index type - tt = parsedef(&p, nil); - if(tt == nil) - return nil; - t->size = tt->size; - // element type - tt = parsedef(&p, nil); - if(tt == nil) - return nil; - t->type = tt; - break; - - case 'e': // enum type - record $names in con array. - p++; - for(;;) { - if(*p == '\0') - return nil; - if(*p == ';') { - p++; - break; - } - if(parsename(&p, &name) < 0) - return nil; - if(parsenum1(&p, &n1) < 0) - return nil; - if(name[0] == '$') { - con = erealloc(con, (ncon+1)*sizeof con[0]); - name++; - con[ncon].name = name; - con[ncon].value = n1; - ncon++; - } - if(*p != ',') - return nil; - p++; - } - break; - - case 'f': // function - p++; - if(parsedef(&p, nil) == nil) - return nil; - break; - - case 'B': // volatile - case 'k': // const - ++*pp; - return parsedef(pp, nil); - - case 'r': // sub-range (used for integers) - p++; - if(parsedef(&p, nil) == nil) - return nil; - // usually, the return from parsedef == t, but not always. - - if(*p != ';' || *++p == ';') { - if(stabsdebug) - fprint(2, "range expected number: %s\n", p); - return nil; - } - if(*p == '0') - lo = parseoctal(&p); - else - lo = strtoll(p, &p, 10); - if(*p != ';' || *++p == ';') { - if(stabsdebug) - fprint(2, "range expected number: %s\n", p); - return nil; - } - if(*p == '0') - hi = parseoctal(&p); - else - hi = strtoll(p, &p, 10); - if(*p != ';') { - if(stabsdebug) - fprint(2, "range expected trailing semi: %s\n", p); - return nil; - } - p++; - t->size = hi+1; // might be array size - for(i=0; i<nelem(intranges); i++) { - r = &intranges[i]; - if(r->lo == lo && r->hi == hi) { - t->kind = r->kind; - break; - } - } - break; - - case 's': // struct - case 'u': // union - t->kind = Struct; - if(*p == 'u') - t->kind = Union; - - // assign given name, but do not record in typ. - // assume the name came from a typedef - // which will be recorded. - if(name) - t->name = name; - p++; - if(parsenum1(&p, &n1) < 0) - return nil; - t->size = n1; - for(;;) { - if(*p == '\0') - return nil; - if(*p == ';') { - p++; - break; - } - t->f = erealloc(t->f, (t->nf+1)*sizeof t->f[0]); - f = &t->f[t->nf]; - if(parsename(&p, &f->name) < 0) - return nil; - f->type = parsedef(&p, nil); - if(f->type == nil) - return nil; - if(*p != ',') { - fprint(2, "expected comma after def of %s:\n%s\n", f->name, p); - return nil; - } - p++; - if(parsenum1(&p, &n1) < 0) - return nil; - f->offset = n1; - if(*p != ',') { - fprint(2, "expected comma after offset of %s:\n%s\n", f->name, p); - return nil; - } - p++; - if(parsenum1(&p, &n1) < 0) - return nil; - f->size = n1; - if(*p != ';') { - fprint(2, "expected semi after size of %s:\n%s\n", f->name, p); - return nil; - } - - while(f->type->kind == Typedef) - f->type = f->type->type; - - // rewrite - // uint32 x : 8; - // into - // uint8 x; - // hooray for bitfields. - while(Int16 <= f->type->kind && f->type->kind <= Uint64 && kindsize[f->type->kind] > f->size) { - tt = emalloc(sizeof *tt); - *tt = *f->type; - f->type = tt; - f->type->kind -= 2; - } - p++; - t->nf++; - } - break; - - case 'x': - // reference to struct, union not yet defined. - p++; - switch(*p) { - case 's': - t->kind = Struct; - break; - case 'u': - t->kind = Union; - break; - default: - fprint(2, "unknown x type char x%c", *p); - *pp = ""; - return t; - } - if(parsename(&p, &t->name) < 0) - return nil; - break; - } - *pp = p; - return t; -} - - -// Parse a stab type in p, saving info in the type hash table -// and also in the list of recorded types if appropriate. -void -parsestabtype(char *p) -{ - char *p0, *name; - - p0 = p; - - // p is the quoted string output from gcc -gstabs on a .stabs line. - // name:t(1,2) - // name:t(1,2)=def - if(parsename(&p, &name) < 0) { - Bad: - // Use fprint instead of sysfatal to avoid - // sysfatal's internal buffer size limit. - fprint(2, "cannot parse stabs type:\n%s\n(at %s)\n", p0, p); - sysfatal("stabs parse"); - } - if(*p != 't' && *p != 'T') - goto Bad; - p++; - - // parse the definition. - if(name[0] == '\0') - name = nil; - if(parsedef(&p, name) == nil) - goto Bad; - if(*p != '\0') - goto Bad; -} - |