summaryrefslogtreecommitdiff
path: root/src/cmd/godefs/stabs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/godefs/stabs.c')
-rw-r--r--src/cmd/godefs/stabs.c456
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;
-}
-