summaryrefslogtreecommitdiff
path: root/src/cmd/godefs
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/godefs')
-rw-r--r--src/cmd/godefs/Makefile19
-rw-r--r--src/cmd/godefs/a.h104
-rw-r--r--src/cmd/godefs/doc.go99
-rw-r--r--src/cmd/godefs/main.c609
-rw-r--r--src/cmd/godefs/stabs.c456
-rwxr-xr-xsrc/cmd/godefs/test.sh45
-rw-r--r--src/cmd/godefs/testdata.c41
-rw-r--r--src/cmd/godefs/testdata_darwin_386.golden31
-rw-r--r--src/cmd/godefs/testdata_darwin_amd64.golden31
-rw-r--r--src/cmd/godefs/util.c36
10 files changed, 0 insertions, 1471 deletions
diff --git a/src/cmd/godefs/Makefile b/src/cmd/godefs/Makefile
deleted file mode 100644
index 77cd26c04..000000000
--- a/src/cmd/godefs/Makefile
+++ /dev/null
@@ -1,19 +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.
-
-include ../../Make.inc
-O:=$(HOST_O)
-
-TARG=godefs
-OFILES=\
- main.$O\
- stabs.$O\
- util.$O\
-
-HFILES=a.h
-
-include ../../Make.ccmd
-
-test: $(TARG)
- ./test.sh
diff --git a/src/cmd/godefs/a.h b/src/cmd/godefs/a.h
deleted file mode 100644
index 9b4957467..000000000
--- a/src/cmd/godefs/a.h
+++ /dev/null
@@ -1,104 +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.
-
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-
-enum
-{
- Void = 1,
- Int8,
- Uint8,
- Int16,
- Uint16,
- Int32,
- Uint32,
- Int64,
- Uint64,
- Float32,
- Float64,
- Ptr,
- Struct,
- Array,
- Union,
- Typedef,
-};
-
-typedef struct Field Field;
-typedef struct Type Type;
-
-struct Type
-{
- Type *next; // next in hash table
-
- // stabs name and two-integer id
- char *name;
- int n1;
- int n2;
-
- // int kind
- int kind;
-
- // sub-type for ptr, array
- Type *type;
-
- // struct fields
- Field *f;
- int nf;
- int size;
-
- int saved; // recorded in typ array
- int warned; // warned about needing type
- int printed; // has the definition been printed yet?
-};
-
-struct Field
-{
- char *name;
- Type *type;
- int offset;
- int size;
-};
-
-// Constants
-typedef struct Const Const;
-struct Const
-{
- char *name;
- vlong value;
-};
-
-// Recorded constants and types, to be printed.
-extern Const *con;
-extern int ncon;
-extern Type **typ;
-extern int ntyp;
-extern int kindsize[];
-
-// Language output
-typedef struct Lang Lang;
-struct Lang
-{
- char *constbegin;
- char *constfmt;
- char *constend;
-
- char *typdef;
- char *typdefend;
-
- char *structbegin;
- char *unionbegin;
- char *structpadfmt;
- char *structend;
-
- int (*typefmt)(Fmt*);
-};
-
-extern Lang go, c;
-
-void* emalloc(int);
-char* estrdup(char*);
-void* erealloc(void*, int);
-void parsestabtype(char*);
diff --git a/src/cmd/godefs/doc.go b/src/cmd/godefs/doc.go
deleted file mode 100644
index 365c7cf6e..000000000
--- a/src/cmd/godefs/doc.go
+++ /dev/null
@@ -1,99 +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.
-
-/*
-
-Godefs is a bootstrapping tool for porting the Go runtime to new systems.
-It translates C type declarations into C or Go type declarations
-with the same memory layout.
-
-Usage: godefs [-g package] [-c cc] [-f cc-arg]... [defs.c ...]
-
-Godefs takes as input a host-compilable C file that includes
-standard system headers. From that input file, it generates
-a standalone (no #includes) C or Go file containing equivalent
-definitions.
-
-The input to godefs is a C input file that can be compiled by
-the host system's standard C compiler (typically gcc).
-This file is expected to define new types and enumerated constants
-whose names begin with $ (a legal identifier character in gcc).
-Godefs compile the given input file with the host compiler and
-then parses the debug info embedded in the assembly output.
-This is far easier than reading system headers on most machines.
-
-The output from godefs is either C output intended for the
-Plan 9 C compiler tool chain (6c, 8c, or 5c) or Go output.
-
-The options are:
-
- -g package
- generate Go output using the given package name.
- In the Go output, struct fields have leading xx_ prefixes
- removed and the first character capitalized (exported).
-
- -c cc
- set the name of the host system's C compiler (default "gcc")
-
- -f cc-arg
- add cc-arg to the command line when invoking the system C compiler
- (for example, -f -m64 to invoke gcc -m64).
- Repeating this option adds multiple flags to the command line.
-
-For example, if this is x.c:
-
- #include <sys/stat.h>
-
- typedef struct timespec $Timespec;
- enum {
- $S_IFMT = S_IFMT,
- $S_IFIFO = S_IFIFO,
- $S_IFCHR = S_IFCHR,
- };
-
-then "godefs x.c" generates:
-
- // godefs x.c
- // MACHINE GENERATED - DO NOT EDIT.
-
- // Constants
- enum {
- S_IFMT = 0xf000,
- S_IFIFO = 0x1000,
- S_IFCHR = 0x2000,
- };
-
- // Types
- #pragma pack on
-
- typedef struct Timespec Timespec;
- struct Timespec {
- int64 tv_sec;
- int64 tv_nsec;
- };
- #pragma pack off
-
-and "godefs -g MyPackage x.c" generates:
-
- // godefs -g MyPackage x.c
- // MACHINE GENERATED - DO NOT EDIT.
-
- package MyPackage
-
- // Constants
- const (
- S_IFMT = 0xf000;
- S_IFIFO = 0x1000;
- S_IFCHR = 0x2000;
- )
-
- // Types
-
- type Timespec struct {
- Sec int64;
- Nsec int64;
- }
-
-*/
-package documentation
diff --git a/src/cmd/godefs/main.c b/src/cmd/godefs/main.c
deleted file mode 100644
index 38b2962fa..000000000
--- a/src/cmd/godefs/main.c
+++ /dev/null
@@ -1,609 +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.
-
-// Godefs takes as input a host-compilable C file that includes
-// standard system headers. From that input file, it generates
-// a standalone (no #includes) C or Go file containing equivalent
-// definitions.
-//
-// The input C file is expected to define new types and enumerated
-// constants whose names begin with $ (a legal identifier character
-// in gcc). The output is the standalone definitions of those names,
-// with the $ removed.
-//
-// For example, if this is x.c:
-//
-// #include <sys/stat.h>
-//
-// typedef struct timespec $Timespec;
-// typedef struct stat $Stat;
-// enum {
-// $S_IFMT = S_IFMT,
-// $S_IFIFO = S_IFIFO,
-// $S_IFCHR = S_IFCHR,
-// };
-//
-// then "godefs x.c" generates:
-//
-// // godefs x.c
-//
-// // MACHINE GENERATED - DO NOT EDIT.
-//
-// // Constants
-// enum {
-// S_IFMT = 0xf000,
-// S_IFIFO = 0x1000,
-// S_IFCHR = 0x2000,
-// };
-//
-// // Types
-// #pragma pack on
-//
-// typedef struct Timespec Timespec;
-// struct Timespec {
-// int32 tv_sec;
-// int32 tv_nsec;
-// };
-//
-// typedef struct Stat Stat;
-// struct Stat {
-// int32 st_dev;
-// uint32 st_ino;
-// uint16 st_mode;
-// uint16 st_nlink;
-// uint32 st_uid;
-// uint32 st_gid;
-// int32 st_rdev;
-// Timespec st_atimespec;
-// Timespec st_mtimespec;
-// Timespec st_ctimespec;
-// int64 st_size;
-// int64 st_blocks;
-// int32 st_blksize;
-// uint32 st_flags;
-// uint32 st_gen;
-// int32 st_lspare;
-// int64 st_qspare[2];
-// };
-// #pragma pack off
-//
-// The -g flag to godefs causes it to generate Go output, not C.
-// In the Go output, struct fields have leading xx_ prefixes removed
-// and the first character capitalized (exported).
-//
-// Godefs works by invoking gcc to compile the given input file
-// and then parses the debug info embedded in the assembly output.
-// This is far easier than reading system headers on most machines.
-//
-// The -c flag sets the compiler (default "gcc").
-//
-// The -f flag adds a flag to pass to the compiler (e.g., -f -m64).
-
-#include "a.h"
-
-#ifdef _WIN32
-int
-spawn(char *prog, char **argv)
-{
- return _spawnvp(P_NOWAIT, prog, (const char**)argv);
-}
-#undef waitfor
-void
-waitfor(int pid)
-{
- _cwait(0, pid, 0);
-}
-#else
-int
-spawn(char *prog, char **argv)
-{
- int pid;
-
- USED(prog);
- pid = fork();
- if(pid < 0)
- sysfatal("fork: %r");
- if(pid == 0) {
- exec(argv[0], argv);
- fprint(2, "exec gcc: %r\n");
- exit(1);
- }
- return pid;
-}
-#endif
-
-void
-usage(void)
-{
- fprint(2, "usage: godefs [-g package] [-c cc] [-f cc-arg] [defs.c ...]\n");
- exit(1);
-}
-
-int gotypefmt(Fmt*);
-int ctypefmt(Fmt*);
-int prefixlen(Type*);
-int cutprefix(char*);
-
-Lang go =
-{
- "const (\n",
- "\t%s = %#llx;\n",
- ")\n",
-
- "type",
- "\n",
-
- "type %s struct {\n",
- "type %s struct {\n",
- "\tPad_godefs_%d [%d]byte;\n",
- "}\n",
-
- gotypefmt,
-};
-
-Lang c =
-{
- "enum {\n",
- "\t%s = %#llx,\n",
- "};\n",
-
- "typedef",
- ";\n",
-
- "typedef struct %s %s;\nstruct %s {\n",
- "typedef union %s %s;\nunion %s {\n",
- "\tbyte pad_godefs_%d[%d];\n",
- "};\n",
-
- ctypefmt,
-};
-
-char *pkg;
-
-int oargc;
-char **oargv;
-Lang *lang = &c;
-
-Const *con;
-int ncon;
-
-Type **typ;
-int ntyp;
-
-void
-waitforgcc(void)
-{
- waitpid();
-}
-
-void
-main(int argc, char **argv)
-{
- int p[2], pid, i, j, n, off, npad, prefix;
- char **av, *q, *r, *tofree, *name;
- char nambuf[100];
- Biobuf *bin, *bout;
- Type *t, *tt;
- Field *f;
- int orig_output_fd;
-
- quotefmtinstall();
-
- oargc = argc;
- oargv = argv;
- av = emalloc((30+argc)*sizeof av[0]);
- atexit(waitforgcc);
-
- n = 0;
- av[n++] = "gcc";
- av[n++] = "-fdollars-in-identifiers";
- av[n++] = "-S"; // write assembly
- av[n++] = "-gstabs+"; // include stabs info
- av[n++] = "-o"; // to ...
- av[n++] = "-"; // ... stdout
- av[n++] = "-xc"; // read C
-
- ARGBEGIN{
- case 'g':
- lang = &go;
- pkg = EARGF(usage());
- break;
- case 'c':
- av[0] = EARGF(usage());
- break;
- case 'f':
- av[n++] = EARGF(usage());
- break;
- default:
- usage();
- }ARGEND
-
- if(argc == 0)
- av[n++] = "-";
- else
- av[n++] = argv[0];
- av[n] = nil;
-
- orig_output_fd = dup(1, -1);
- for(i=0; i==0 || i < argc; i++) {
- // Some versions of gcc do not accept -S with multiple files.
- // Run gcc once for each file.
- // Write assembly and stabs debugging to p[1].
- if(pipe(p) < 0)
- sysfatal("pipe: %r");
- dup(p[1], 1);
- close(p[1]);
- if (argc)
- av[n-1] = argv[i];
- pid = spawn(av[0], av);
- dup(orig_output_fd, 1);
-
- // Read assembly, pulling out .stabs lines.
- bin = Bfdopen(p[0], OREAD);
- while((q = Brdstr(bin, '\n', 1)) != nil) {
- // .stabs "float:t(0,12)=r(0,1);4;0;",128,0,0,0
- tofree = q;
- while(*q == ' ' || *q == '\t')
- q++;
- if(strncmp(q, ".stabs", 6) != 0)
- goto Continue;
- q += 6;
- while(*q == ' ' || *q == '\t')
- q++;
- if(*q++ != '\"') {
-Bad:
- sysfatal("cannot parse .stabs line:\n%s", tofree);
- }
-
- r = strchr(q, '\"');
- if(r == nil)
- goto Bad;
- *r++ = '\0';
- if(*r++ != ',')
- goto Bad;
- if(*r < '0' || *r > '9')
- goto Bad;
- if(atoi(r) != 128) // stabs kind = local symbol
- goto Continue;
-
- parsestabtype(q);
-
-Continue:
- free(tofree);
- }
- Bterm(bin);
- waitfor(pid);
- }
- close(orig_output_fd);
-
- // Write defs to standard output.
- bout = Bfdopen(1, OWRITE);
- fmtinstall('T', lang->typefmt);
-
- // Echo original command line in header.
- Bprint(bout, "//");
- for(i=0; i<oargc; i++)
- Bprint(bout, " %q", oargv[i]);
- Bprint(bout, "\n");
- Bprint(bout, "\n");
- Bprint(bout, "// MACHINE GENERATED - DO NOT EDIT.\n");
- Bprint(bout, "\n");
-
- if(pkg)
- Bprint(bout, "package %s\n\n", pkg);
-
- // Constants.
- Bprint(bout, "// Constants\n");
- if(ncon > 0) {
- Bprint(bout, lang->constbegin);
- for(i=0; i<ncon; i++) {
- // Go can handle negative constants,
- // but C enums may not be able to.
- if(lang == &go)
- Bprint(bout, lang->constfmt, con[i].name, con[i].value);
- else
- Bprint(bout, lang->constfmt, con[i].name, con[i].value & 0xFFFFFFFF);
- }
- Bprint(bout, lang->constend);
- }
- Bprint(bout, "\n");
-
- // Types
-
- // push our names down
- for(i=0; i<ntyp; i++) {
- t = typ[i];
- name = t->name;
- while(t && t->kind == Typedef)
- t = t->type;
- if(t)
- t->name = name;
- }
-
- Bprint(bout, "// Types\n");
-
- // Have to turn off structure padding in Plan 9 compiler,
- // mainly because it is more aggressive than gcc tends to be.
- if(lang == &c)
- Bprint(bout, "#pragma pack on\n");
-
- for(i=0; i<ntyp; i++) {
- Bprint(bout, "\n");
- t = typ[i];
- name = t->name;
- while(t && t->kind == Typedef) {
- if(name == nil && t->name != nil) {
- name = t->name;
- if(t->printed)
- break;
- }
- t = t->type;
- }
- if(name == nil && t->name != nil) {
- name = t->name;
- if(t->printed)
- continue;
- t->printed = 1;
- }
- if(name == nil) {
- fprint(2, "unknown name for %T", typ[i]);
- continue;
- }
- if(name[0] == '$')
- name++;
- npad = 0;
- off = 0;
- switch(t->kind) {
- case 0:
- fprint(2, "unknown type definition for %s\n", name);
- break;
- default: // numeric, array, or pointer
- case Array:
- case Ptr:
- Bprint(bout, "%s %lT%s", lang->typdef, name, t, lang->typdefend);
- break;
- case Union:
- // In Go, print union as struct with only first element,
- // padded the rest of the way.
- Bprint(bout, lang->unionbegin, name, name, name);
- goto StructBody;
- case Struct:
- Bprint(bout, lang->structbegin, name, name, name);
- StructBody:
- prefix = 0;
- if(lang == &go)
- prefix = prefixlen(t);
- for(j=0; j<t->nf; j++) {
- f = &t->f[j];
- if(f->type->kind == 0 && f->size <= 64 && (f->size&(f->size-1)) == 0) {
- // unknown type but <= 64 bits and bit size is a power of two.
- // could be enum - make Uint64 and then let it reduce
- tt = emalloc(sizeof *tt);
- *tt = *f->type;
- f->type = tt;
- tt->kind = Uint64;
- while(tt->kind > Uint8 && kindsize[tt->kind] > f->size)
- tt->kind -= 2;
- }
- // padding
- if(t->kind == Struct || lang == &go) {
- if(f->offset%8 != 0 || f->size%8 != 0) {
- fprint(2, "ignoring bitfield %s.%s\n", t->name, f->name);
- continue;
- }
- if(f->offset < off)
- sysfatal("%s: struct fields went backward", t->name);
- if(off < f->offset) {
- Bprint(bout, lang->structpadfmt, npad++, (f->offset - off) / 8);
- off = f->offset;
- }
- off += f->size;
- }
- name = f->name;
- if(cutprefix(name))
- name += prefix;
- if(strcmp(name, "") == 0) {
- snprint(nambuf, sizeof nambuf, "Pad_godefs_%d", npad++);
- name = nambuf;
- }
- Bprint(bout, "\t%#lT;\n", name, f->type);
- if(t->kind == Union && lang == &go)
- break;
- }
- // final padding
- if(t->kind == Struct || lang == &go) {
- if(off/8 < t->size)
- Bprint(bout, lang->structpadfmt, npad++, t->size - off/8);
- }
- Bprint(bout, lang->structend);
- }
- }
- if(lang == &c)
- Bprint(bout, "#pragma pack off\n");
- Bterm(bout);
- exit(0);
-}
-
-char *kindnames[] = {
- "void", // actually unknown, but byte is good for pointers
- "void",
- "int8",
- "uint8",
- "int16",
- "uint16",
- "int32",
- "uint32",
- "int64",
- "uint64",
- "float32",
- "float64",
- "ptr",
- "struct",
- "array",
- "union",
- "typedef",
-};
-
-int
-ctypefmt(Fmt *f)
-{
- char *name, *s;
- Type *t;
-
- name = nil;
- if(f->flags & FmtLong) {
- name = va_arg(f->args, char*);
- if(name == nil || name[0] == '\0')
- name = "_anon_";
- }
- t = va_arg(f->args, Type*);
- while(t && t->kind == Typedef)
- t = t->type;
- switch(t->kind) {
- case Struct:
- case Union:
- // must be named
- s = t->name;
- if(s == nil) {
- fprint(2, "need name for anonymous struct\n");
- goto bad;
- }
- else if(s[0] != '$')
- fprint(2, "need name for struct %s\n", s);
- else
- s++;
- fmtprint(f, "%s", s);
- if(name)
- fmtprint(f, " %s", name);
- break;
-
- case Array:
- if(name)
- fmtprint(f, "%T %s[%d]", t->type, name, t->size);
- else
- fmtprint(f, "%T[%d]", t->type, t->size);
- break;
-
- case Ptr:
- if(name)
- fmtprint(f, "%T *%s", t->type, name);
- else
- fmtprint(f, "%T*", t->type);
- break;
-
- default:
- fmtprint(f, "%s", kindnames[t->kind]);
- if(name)
- fmtprint(f, " %s", name);
- break;
-
- bad:
- if(name)
- fmtprint(f, "byte %s[%d]", name, t->size);
- else
- fmtprint(f, "byte[%d]", t->size);
- break;
- }
-
- return 0;
-}
-
-int
-gotypefmt(Fmt *f)
-{
- char *name, *s;
- Type *t;
-
- if(f->flags & FmtLong) {
- name = va_arg(f->args, char*);
- if('a' <= name[0] && name[0] <= 'z')
- name[0] += 'A' - 'a';
- if(name[0] == '_' && (f->flags & FmtSharp))
- fmtprint(f, "X");
- fmtprint(f, "%s ", name);
- }
- t = va_arg(f->args, Type*);
- while(t && t->kind == Typedef)
- t = t->type;
-
- switch(t->kind) {
- case Struct:
- case Union:
- // must be named
- s = t->name;
- if(s == nil) {
- fprint(2, "need name for anonymous struct\n");
- fmtprint(f, "STRUCT");
- }
- else if(s[0] != '$') {
- fprint(2, "warning: missing name for struct %s\n", s);
- fmtprint(f, "[%d]byte /* %s */", t->size, s);
- } else
- fmtprint(f, "%s", s+1);
- break;
-
- case Array:
- fmtprint(f, "[%d]%T", t->size, t->type);
- break;
-
- case Ptr:
- fmtprint(f, "*%T", t->type);
- break;
-
- default:
- s = kindnames[t->kind];
- if(strcmp(s, "void") == 0)
- s = "byte";
- fmtprint(f, "%s", s);
- }
-
- return 0;
-}
-
-// Is this the kind of name we should cut a prefix from?
-// The rule is that the name cannot begin with underscore
-// and must have an underscore eventually.
-int
-cutprefix(char *name)
-{
- char *p;
-
- // special case: orig_ in register struct
- if(strncmp(name, "orig_", 5) == 0)
- return 0;
-
- for(p=name; *p; p++) {
- if(*p == '_')
- return p-name > 0;
- }
- return 0;
-}
-
-// Figure out common struct prefix len
-int
-prefixlen(Type *t)
-{
- int i;
- int len;
- char *p, *name;
- Field *f;
-
- len = 0;
- name = nil;
- for(i=0; i<t->nf; i++) {
- f = &t->f[i];
- if(!cutprefix(f->name))
- continue;
- p = strchr(f->name, '_');
- if(p == nil)
- return 0;
- if(name == nil) {
- name = f->name;
- len = p+1 - name;
- }
- else if(strncmp(f->name, name, len) != 0)
- return 0;
- }
- return len;
-}
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;
-}
-
diff --git a/src/cmd/godefs/test.sh b/src/cmd/godefs/test.sh
deleted file mode 100755
index c035af8f4..000000000
--- a/src/cmd/godefs/test.sh
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env bash
-# Copyright 2011 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.
-
-eval $(gomake --no-print-directory -f ../../Make.inc go-env)
-
-TMP="testdata_tmp.go"
-TEST="testdata.c"
-GOLDEN="testdata_${GOOS}_${GOARCH}.golden"
-
-case ${GOARCH} in
-"amd64") CCARG="-f-m64";;
-"386") CCARG="-f-m32";;
-*) CCARG="";;
-esac
-
-cleanup() {
- rm ${TMP}
-}
-
-error() {
- cleanup
- echo $1
- exit 1
-}
-
-if [ ! -e ${GOLDEN} ]; then
- echo "skipping - no golden defined for this platform"
- exit
-fi
-
-./godefs -g test ${CCARG} ${TEST} > ${TMP}
-if [ $? != 0 ]; then
- error "Error: Could not run godefs for ${TEST}"
-fi
-
-diff ${TMP} ${GOLDEN}
-if [ $? != 0 ]; then
- error "FAIL: godefs for ${TEST} did not match ${GOLDEN}"
-fi
-
-cleanup
-
-echo "PASS"
diff --git a/src/cmd/godefs/testdata.c b/src/cmd/godefs/testdata.c
deleted file mode 100644
index 3f459c41b..000000000
--- a/src/cmd/godefs/testdata.c
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2011 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 <stdint.h>
-
-// Issue 432 - enum fields in struct can cause misaligned struct fields
-typedef enum {
- a
-} T1;
-
-struct T2 {
- uint8_t a;
- T1 b;
- T1 c;
- uint16_t d;
-};
-
-typedef struct T2 T2;
-typedef T2 $T2;
-
-// Issue 1162 - structs with fields named Pad[0-9]+ conflict with field
-// names used by godefs for padding
-struct T3 {
- uint8_t a;
- int Pad0;
-};
-
-typedef struct T3 $T3;
-
-// Issue 1466 - forward references to types in stabs debug info were
-// always treated as enums
-struct T4 {};
-
-struct T5 {
- struct T4 *a;
-};
-
-typedef struct T5 T5;
-typedef struct T4 $T4;
-typedef T5 $T5; \ No newline at end of file
diff --git a/src/cmd/godefs/testdata_darwin_386.golden b/src/cmd/godefs/testdata_darwin_386.golden
deleted file mode 100644
index d929238b0..000000000
--- a/src/cmd/godefs/testdata_darwin_386.golden
+++ /dev/null
@@ -1,31 +0,0 @@
-// ./godefs -g test -f-m32 testdata.c
-
-// MACHINE GENERATED - DO NOT EDIT.
-
-package test
-
-// Constants
-
-// Types
-
-type T2 struct {
- A uint8;
- Pad_godefs_0 [3]byte;
- B uint32;
- C uint32;
- D uint16;
- Pad_godefs_1 [2]byte;
-}
-
-type T3 struct {
- A uint8;
- Pad_godefs_0 [3]byte;
- Pad0 int32;
-}
-
-type T4 struct {
-}
-
-type T5 struct {
- A *T4;
-}
diff --git a/src/cmd/godefs/testdata_darwin_amd64.golden b/src/cmd/godefs/testdata_darwin_amd64.golden
deleted file mode 100644
index a694f4a73..000000000
--- a/src/cmd/godefs/testdata_darwin_amd64.golden
+++ /dev/null
@@ -1,31 +0,0 @@
-// ./godefs -g test -f-m64 testdata.c
-
-// MACHINE GENERATED - DO NOT EDIT.
-
-package test
-
-// Constants
-
-// Types
-
-type T2 struct {
- A uint8;
- Pad_godefs_0 [3]byte;
- B uint32;
- C uint32;
- D uint16;
- Pad_godefs_1 [2]byte;
-}
-
-type T3 struct {
- A uint8;
- Pad_godefs_0 [3]byte;
- Pad0 int32;
-}
-
-type T4 struct {
-}
-
-type T5 struct {
- A *T4;
-}
diff --git a/src/cmd/godefs/util.c b/src/cmd/godefs/util.c
deleted file mode 100644
index 18be00453..000000000
--- a/src/cmd/godefs/util.c
+++ /dev/null
@@ -1,36 +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.
-
-#include "a.h"
-
-void*
-emalloc(int n)
-{
- void *p;
-
- p = malloc(n);
- if(p == nil)
- sysfatal("out of memory");
- memset(p, 0, n);
- return p;
-}
-
-char*
-estrdup(char *s)
-{
- s = strdup(s);
- if(s == nil)
- sysfatal("out of memory");
- return s;
-}
-
-void*
-erealloc(void *v, int n)
-{
- v = realloc(v, n);
- if(v == nil)
- sysfatal("out of memory");
- return v;
-}
-