2009-03-31 01:22:59 -06:00
|
|
|
// 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.
|
|
|
|
|
|
|
|
#ifndef EXTERN
|
2011-07-28 16:22:12 -06:00
|
|
|
#define EXTERN extern
|
2009-03-31 01:22:59 -06:00
|
|
|
#endif
|
|
|
|
|
2011-08-23 20:39:14 -06:00
|
|
|
#include "../gc/go.h"
|
|
|
|
#include "../8l/8.out.h"
|
|
|
|
|
2009-03-31 01:22:59 -06:00
|
|
|
typedef struct Addr Addr;
|
|
|
|
|
|
|
|
struct Addr
|
|
|
|
{
|
|
|
|
int32 offset;
|
|
|
|
int32 offset2;
|
|
|
|
|
2012-12-13 12:20:24 -07:00
|
|
|
union {
|
|
|
|
double dval;
|
|
|
|
vlong vval;
|
|
|
|
Prog* branch;
|
|
|
|
char sval[NSNAME];
|
|
|
|
} u;
|
2009-03-31 01:22:59 -06:00
|
|
|
|
2009-11-06 17:51:49 -07:00
|
|
|
Sym* gotype;
|
2009-03-31 01:22:59 -06:00
|
|
|
Sym* sym;
|
2011-06-09 16:02:34 -06:00
|
|
|
Node* node;
|
2009-11-06 17:51:49 -07:00
|
|
|
int width;
|
2009-03-31 01:22:59 -06:00
|
|
|
uchar type;
|
|
|
|
uchar index;
|
|
|
|
uchar etype;
|
|
|
|
uchar scale; /* doubles as width in DATA op */
|
|
|
|
};
|
|
|
|
#define A ((Addr*)0)
|
|
|
|
|
|
|
|
struct Prog
|
|
|
|
{
|
|
|
|
short as; // opcode
|
|
|
|
uint32 loc; // pc offset in this func
|
|
|
|
uint32 lineno; // source line that generated this
|
|
|
|
Addr from; // src address
|
|
|
|
Addr to; // dst address
|
|
|
|
Prog* link; // next instruction in this func
|
2013-08-12 17:14:02 -06:00
|
|
|
void* opt; // for optimizer passes
|
2009-03-31 01:22:59 -06:00
|
|
|
};
|
|
|
|
|
2011-12-12 20:22:09 -07:00
|
|
|
#define TEXTFLAG from.scale
|
|
|
|
|
2009-05-28 16:48:47 -06:00
|
|
|
// foptoas flags
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
Frev = 1<<0,
|
|
|
|
Fpop = 1<<1,
|
|
|
|
Fpop2 = 1<<2,
|
|
|
|
};
|
|
|
|
|
2009-03-31 01:22:59 -06:00
|
|
|
EXTERN int32 dynloc;
|
|
|
|
EXTERN uchar reg[D_NONE];
|
|
|
|
EXTERN int32 pcloc; // instruction counter
|
2009-05-26 15:46:06 -06:00
|
|
|
EXTERN Strlit emptystring;
|
2009-03-31 01:22:59 -06:00
|
|
|
extern char* anames[];
|
|
|
|
EXTERN Prog zprog;
|
|
|
|
EXTERN Node* newproc;
|
|
|
|
EXTERN Node* deferproc;
|
|
|
|
EXTERN Node* deferreturn;
|
2010-04-01 23:31:27 -06:00
|
|
|
EXTERN Node* panicindex;
|
|
|
|
EXTERN Node* panicslice;
|
2009-03-31 01:22:59 -06:00
|
|
|
EXTERN Node* throwreturn;
|
2009-04-02 17:48:06 -06:00
|
|
|
EXTERN int maxstksize;
|
2009-11-01 22:04:16 -07:00
|
|
|
extern uint32 unmappedzero;
|
|
|
|
|
2009-03-31 01:22:59 -06:00
|
|
|
|
|
|
|
/*
|
2009-06-03 00:25:17 -06:00
|
|
|
* ggen.c
|
2009-03-31 01:22:59 -06:00
|
|
|
*/
|
|
|
|
void compile(Node*);
|
|
|
|
void gen(Node*);
|
|
|
|
Node* lookdot(Node*, Node*, int);
|
|
|
|
void cgen_as(Node*, Node*);
|
|
|
|
void cgen_callmeth(Node*, int);
|
|
|
|
void cgen_callinter(Node*, Node*, int);
|
|
|
|
void cgen_proc(Node*, int);
|
|
|
|
void cgen_callret(Node*, Node*);
|
|
|
|
void cgen_div(int, Node*, Node*, Node*);
|
|
|
|
void cgen_bmul(int, Node*, Node*, Node*);
|
2012-11-26 15:45:22 -07:00
|
|
|
void cgen_hmul(Node*, Node*, Node*);
|
2012-05-24 15:20:07 -06:00
|
|
|
void cgen_shift(int, int, Node*, Node*, Node*);
|
2013-01-02 14:55:23 -07:00
|
|
|
void cgen_float(Node*, Node*);
|
|
|
|
void bgen_float(Node *n, int true, int likely, Prog *to);
|
2009-03-31 01:22:59 -06:00
|
|
|
void cgen_dcl(Node*);
|
|
|
|
int needconvert(Type*, Type*);
|
|
|
|
void genconv(Type*, Type*);
|
|
|
|
void allocparams(void);
|
2013-02-05 06:43:04 -07:00
|
|
|
void checklabels(void);
|
2009-03-31 01:22:59 -06:00
|
|
|
void ginscall(Node*, int);
|
|
|
|
|
|
|
|
/*
|
2009-06-03 00:25:17 -06:00
|
|
|
* cgen.c
|
2009-03-31 01:22:59 -06:00
|
|
|
*/
|
|
|
|
void agen(Node*, Node*);
|
|
|
|
void igen(Node*, Node*, Node*);
|
|
|
|
vlong fieldoffset(Type*, Node*);
|
2012-01-10 03:19:22 -07:00
|
|
|
void sgen(Node*, Node*, int64);
|
2009-03-31 01:22:59 -06:00
|
|
|
void gmove(Node*, Node*);
|
|
|
|
Prog* gins(int, Node*, Node*);
|
|
|
|
int samaddr(Node*, Node*);
|
2009-11-01 22:04:16 -07:00
|
|
|
void naddr(Node*, Addr*, int);
|
2009-03-31 01:22:59 -06:00
|
|
|
void cgen_aret(Node*, Node*);
|
2009-05-29 01:13:09 -06:00
|
|
|
Node* ncon(uint32);
|
2010-03-08 15:19:28 -07:00
|
|
|
void mgen(Node*, Node*, Node*);
|
|
|
|
void mfree(Node*);
|
2012-09-09 12:30:08 -06:00
|
|
|
int componentgen(Node*, Node*);
|
2009-03-31 01:22:59 -06:00
|
|
|
|
2009-06-03 00:25:17 -06:00
|
|
|
/*
|
|
|
|
* cgen64.c
|
|
|
|
*/
|
2012-05-30 16:07:39 -06:00
|
|
|
void cmp64(Node*, Node*, int, int, Prog*);
|
2009-06-03 00:25:17 -06:00
|
|
|
void cgen64(Node*, Node*);
|
|
|
|
|
2009-03-31 01:22:59 -06:00
|
|
|
/*
|
|
|
|
* gsubr.c
|
|
|
|
*/
|
|
|
|
void clearp(Prog*);
|
2012-05-30 16:07:39 -06:00
|
|
|
Prog* gbranch(int, Type*, int);
|
2009-03-31 01:22:59 -06:00
|
|
|
Prog* prog(int);
|
|
|
|
void gconv(int, int);
|
|
|
|
int conv2pt(Type*);
|
|
|
|
vlong convvtox(vlong, int);
|
|
|
|
void fnparam(Type*, int, int);
|
|
|
|
Prog* gop(int, Node*, Node*, Node*);
|
|
|
|
int optoas(int, Type*);
|
2009-05-28 16:48:47 -06:00
|
|
|
int foptoas(int, Type*, int);
|
2009-03-31 01:22:59 -06:00
|
|
|
void ginit(void);
|
|
|
|
void gclean(void);
|
|
|
|
void regalloc(Node*, Type*, Node*);
|
|
|
|
void regfree(Node*);
|
|
|
|
Node* nodarg(Type*, int);
|
|
|
|
void nodreg(Node*, Type*, int);
|
|
|
|
void nodindreg(Node*, Type*, int);
|
2009-06-03 00:25:17 -06:00
|
|
|
void nodconst(Node*, Type*, int64);
|
2009-03-31 01:22:59 -06:00
|
|
|
void gconreg(int, vlong, int);
|
|
|
|
void buildtxt(void);
|
|
|
|
Plist* newplist(void);
|
|
|
|
int isfat(Type*);
|
|
|
|
void sudoclean(void);
|
2009-05-26 17:23:54 -06:00
|
|
|
int sudoaddable(int, Node*, Addr*);
|
2009-05-28 16:48:47 -06:00
|
|
|
int dotaddable(Node*, Node*);
|
2013-02-21 15:01:13 -07:00
|
|
|
void afunclit(Addr*, Node*);
|
2009-05-28 16:48:47 -06:00
|
|
|
void split64(Node*, Node*, Node*);
|
|
|
|
void splitclean(void);
|
2009-06-03 00:25:17 -06:00
|
|
|
void nswap(Node*, Node*);
|
cmd/gc, cmd/ld: struct field tracking
This is an experiment in static analysis of Go programs
to understand which struct fields a program might use.
It is not part of the Go language specification, it must
be enabled explicitly when building the toolchain,
and it may be removed at any time.
After building the toolchain with GOEXPERIMENT=fieldtrack,
a specific field can be marked for tracking by including
`go:"track"` in the field tag:
package pkg
type T struct {
F int `go:"track"`
G int // untracked
}
To simplify usage, only named struct types can have
tracked fields, and only exported fields can be tracked.
The implementation works by making each function begin
with a sequence of no-op USEFIELD instructions declaring
which tracked fields are accessed by a specific function.
After the linker's dead code elimination removes unused
functions, the fields referred to by the remaining
USEFIELD instructions are the ones reported as used by
the binary.
The -k option to the linker specifies the fully qualified
symbol name (such as my/pkg.list) of a string variable that
should be initialized with the field tracking information
for the program. The field tracking string is a sequence
of lines, each terminated by a \n and describing a single
tracked field referred to by the program. Each line is made
up of one or more tab-separated fields. The first field is
the name of the tracked field, fully qualified, as in
"my/pkg.T.F". Subsequent fields give a shortest path of
reverse references from that field to a global variable or
function, corresponding to one way in which the program
might reach that field.
A common source of false positives in field tracking is
types with large method sets, because a reference to the
type descriptor carries with it references to all methods.
To address this problem, the CL also introduces a comment
annotation
//go:nointerface
that marks an upcoming method declaration as unavailable
for use in satisfying interfaces, both statically and
dynamically. Such a method is also invisible to package
reflect.
Again, all of this is disabled by default. It only turns on
if you have GOEXPERIMENT=fieldtrack set during make.bash.
R=iant, ken
CC=golang-dev
https://golang.org/cl/6749064
2012-11-01 22:17:21 -06:00
|
|
|
void gtrack(Sym*);
|
2013-07-16 14:25:10 -06:00
|
|
|
void gargsize(int32);
|
2010-03-09 13:49:24 -07:00
|
|
|
/*
|
|
|
|
* cplx.c
|
|
|
|
*/
|
|
|
|
int complexop(Node*, Node*);
|
|
|
|
void complexmove(Node*, Node*);
|
|
|
|
void complexgen(Node*, Node*);
|
|
|
|
|
2012-09-27 00:34:00 -06:00
|
|
|
/*
|
|
|
|
* gobj.c
|
|
|
|
*/
|
|
|
|
void datastring(char*, int, Addr*);
|
|
|
|
void datagostring(Strlit*, Addr*);
|
|
|
|
|
2009-03-31 01:22:59 -06:00
|
|
|
/*
|
|
|
|
* list.c
|
|
|
|
*/
|
|
|
|
int Aconv(Fmt*);
|
|
|
|
int Dconv(Fmt*);
|
|
|
|
int Pconv(Fmt*);
|
|
|
|
int Rconv(Fmt*);
|
|
|
|
int Yconv(Fmt*);
|
|
|
|
void listinit(void);
|
|
|
|
|
2009-08-13 16:45:58 -06:00
|
|
|
void zaddr(Biobuf*, Addr*, int, int);
|
2009-03-31 01:22:59 -06:00
|
|
|
|
2011-08-26 15:42:59 -06:00
|
|
|
#pragma varargck type "D" Addr*
|
|
|
|
#pragma varargck type "lD" Addr*
|