Commit 3cf1ce40 authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder

Revert "cmd/compile: output DWARF lexical blocks for local variables"

This reverts commit c8b889cc.

Reason for revert: broke noopt build, compiler performance regression, new Curfn uses

Let's fix those and then try this again.

Change-Id: Icc3cad1365d04cac8fd09da9dbb0bbf55c13ef44
Reviewed-on: https://go-review.googlesource.com/39991Reviewed-by: default avatarRobert Griesemer <gri@golang.org>
Reviewed-by: default avatarMatthew Dempsky <mdempsky@google.com>
parent c8b889cc
...@@ -6,7 +6,6 @@ package gc ...@@ -6,7 +6,6 @@ package gc
import ( import (
"cmd/compile/internal/types" "cmd/compile/internal/types"
"cmd/internal/src"
"fmt" "fmt"
) )
...@@ -192,7 +191,7 @@ func genhash(sym *types.Sym, t *types.Type) { ...@@ -192,7 +191,7 @@ func genhash(sym *types.Sym, t *types.Type) {
lineno = autogeneratedPos // less confusing than end of input lineno = autogeneratedPos // less confusing than end of input
dclcontext = PEXTERN dclcontext = PEXTERN
markdcl(src.NoPos) markdcl()
// func sym(p *T, h uintptr) uintptr // func sym(p *T, h uintptr) uintptr
fn := nod(ODCLFUNC, nil, nil) fn := nod(ODCLFUNC, nil, nil)
...@@ -211,7 +210,7 @@ func genhash(sym *types.Sym, t *types.Type) { ...@@ -211,7 +210,7 @@ func genhash(sym *types.Sym, t *types.Type) {
n = anonfield(types.Types[TUINTPTR]) // return value n = anonfield(types.Types[TUINTPTR]) // return value
tfn.Rlist.Append(n) tfn.Rlist.Append(n)
funchdr(fn, src.NoPos) funchdr(fn)
fn.Func.Nname.Name.Param.Ntype = typecheck(fn.Func.Nname.Name.Param.Ntype, Etype) fn.Func.Nname.Name.Param.Ntype = typecheck(fn.Func.Nname.Name.Param.Ntype, Etype)
// genhash is only called for types that have equality but // genhash is only called for types that have equality but
...@@ -300,13 +299,13 @@ func genhash(sym *types.Sym, t *types.Type) { ...@@ -300,13 +299,13 @@ func genhash(sym *types.Sym, t *types.Type) {
dumplist("genhash body", fn.Nbody) dumplist("genhash body", fn.Nbody)
} }
funcbody(fn, src.NoPos) funcbody(fn)
Curfn = fn Curfn = fn
fn.Func.SetDupok(true) fn.Func.SetDupok(true)
fn = typecheck(fn, Etop) fn = typecheck(fn, Etop)
typecheckslice(fn.Nbody.Slice(), Etop) typecheckslice(fn.Nbody.Slice(), Etop)
popdcl(src.NoPos)
Curfn = nil Curfn = nil
popdcl()
if debug_dclstack != 0 { if debug_dclstack != 0 {
testdclstack() testdclstack()
} }
...@@ -370,7 +369,7 @@ func geneq(sym *types.Sym, t *types.Type) { ...@@ -370,7 +369,7 @@ func geneq(sym *types.Sym, t *types.Type) {
lineno = autogeneratedPos // less confusing than end of input lineno = autogeneratedPos // less confusing than end of input
dclcontext = PEXTERN dclcontext = PEXTERN
markdcl(src.NoPos) markdcl()
// func sym(p, q *T) bool // func sym(p, q *T) bool
fn := nod(ODCLFUNC, nil, nil) fn := nod(ODCLFUNC, nil, nil)
...@@ -389,7 +388,7 @@ func geneq(sym *types.Sym, t *types.Type) { ...@@ -389,7 +388,7 @@ func geneq(sym *types.Sym, t *types.Type) {
n = anonfield(types.Types[TBOOL]) n = anonfield(types.Types[TBOOL])
tfn.Rlist.Append(n) tfn.Rlist.Append(n)
funchdr(fn, src.NoPos) funchdr(fn)
fn.Func.Nname.Name.Param.Ntype = typecheck(fn.Func.Nname.Name.Param.Ntype, Etype) fn.Func.Nname.Name.Param.Ntype = typecheck(fn.Func.Nname.Name.Param.Ntype, Etype)
// geneq is only called for types that have equality but // geneq is only called for types that have equality but
...@@ -492,13 +491,13 @@ func geneq(sym *types.Sym, t *types.Type) { ...@@ -492,13 +491,13 @@ func geneq(sym *types.Sym, t *types.Type) {
dumplist("geneq body", fn.Nbody) dumplist("geneq body", fn.Nbody)
} }
funcbody(fn, src.NoPos) funcbody(fn)
Curfn = fn Curfn = fn
fn.Func.SetDupok(true) fn.Func.SetDupok(true)
fn = typecheck(fn, Etop) fn = typecheck(fn, Etop)
typecheckslice(fn.Nbody.Slice(), Etop) typecheckslice(fn.Nbody.Slice(), Etop)
popdcl(src.NoPos)
Curfn = nil Curfn = nil
popdcl()
if debug_dclstack != 0 { if debug_dclstack != 0 {
testdclstack() testdclstack()
} }
......
...@@ -187,7 +187,7 @@ func Import(imp *types.Pkg, in *bufio.Reader) { ...@@ -187,7 +187,7 @@ func Import(imp *types.Pkg, in *bufio.Reader) {
if f := p.funcList[i]; f != nil { if f := p.funcList[i]; f != nil {
// function not yet imported - read body and set it // function not yet imported - read body and set it
funchdr(f, src.NoPos) funchdr(f)
body := p.stmtList() body := p.stmtList()
if body == nil { if body == nil {
// Make sure empty body is not interpreted as // Make sure empty body is not interpreted as
...@@ -198,7 +198,7 @@ func Import(imp *types.Pkg, in *bufio.Reader) { ...@@ -198,7 +198,7 @@ func Import(imp *types.Pkg, in *bufio.Reader) {
body = []*Node{nod(OEMPTY, nil, nil)} body = []*Node{nod(OEMPTY, nil, nil)}
} }
f.Func.Inl.Set(body) f.Func.Inl.Set(body)
funcbody(f, src.NoPos) funcbody(f)
} else { } else {
// function already imported - read body but discard declarations // function already imported - read body but discard declarations
dclcontext = PDISCARD // throw away any declarations dclcontext = PDISCARD // throw away any declarations
...@@ -1091,54 +1091,54 @@ func (p *importer) node() *Node { ...@@ -1091,54 +1091,54 @@ func (p *importer) node() *Node {
return nodl(p.pos(), op, p.expr(), nil) return nodl(p.pos(), op, p.expr(), nil)
case OIF: case OIF:
markdcl(src.NoPos) markdcl()
n := nodl(p.pos(), OIF, nil, nil) n := nodl(p.pos(), OIF, nil, nil)
n.Ninit.Set(p.stmtList()) n.Ninit.Set(p.stmtList())
n.Left = p.expr() n.Left = p.expr()
n.Nbody.Set(p.stmtList()) n.Nbody.Set(p.stmtList())
n.Rlist.Set(p.stmtList()) n.Rlist.Set(p.stmtList())
popdcl(src.NoPos) popdcl()
return n return n
case OFOR: case OFOR:
markdcl(src.NoPos) markdcl()
n := nodl(p.pos(), OFOR, nil, nil) n := nodl(p.pos(), OFOR, nil, nil)
n.Ninit.Set(p.stmtList()) n.Ninit.Set(p.stmtList())
n.Left, n.Right = p.exprsOrNil() n.Left, n.Right = p.exprsOrNil()
n.Nbody.Set(p.stmtList()) n.Nbody.Set(p.stmtList())
popdcl(src.NoPos) popdcl()
return n return n
case ORANGE: case ORANGE:
markdcl(src.NoPos) markdcl()
n := nodl(p.pos(), ORANGE, nil, nil) n := nodl(p.pos(), ORANGE, nil, nil)
n.List.Set(p.stmtList()) n.List.Set(p.stmtList())
n.Right = p.expr() n.Right = p.expr()
n.Nbody.Set(p.stmtList()) n.Nbody.Set(p.stmtList())
popdcl(src.NoPos) popdcl()
return n return n
case OSELECT, OSWITCH: case OSELECT, OSWITCH:
markdcl(src.NoPos) markdcl()
n := nodl(p.pos(), op, nil, nil) n := nodl(p.pos(), op, nil, nil)
n.Ninit.Set(p.stmtList()) n.Ninit.Set(p.stmtList())
n.Left, _ = p.exprsOrNil() n.Left, _ = p.exprsOrNil()
n.List.Set(p.stmtList()) n.List.Set(p.stmtList())
popdcl(src.NoPos) popdcl()
return n return n
// case OCASE, OXCASE: // case OCASE, OXCASE:
// unreachable - mapped to OXCASE case below by exporter // unreachable - mapped to OXCASE case below by exporter
case OXCASE: case OXCASE:
markdcl(src.NoPos) markdcl()
n := nodl(p.pos(), OXCASE, nil, nil) n := nodl(p.pos(), OXCASE, nil, nil)
n.Xoffset = int64(block) n.Xoffset = int64(block)
n.List.Set(p.exprList()) n.List.Set(p.exprList())
// TODO(gri) eventually we must declare variables for type switch // TODO(gri) eventually we must declare variables for type switch
// statements (type switch statements are not yet exported) // statements (type switch statements are not yet exported)
n.Nbody.Set(p.stmtList()) n.Nbody.Set(p.stmtList())
popdcl(src.NoPos) popdcl()
return n return n
// case OFALL: // case OFALL:
......
...@@ -6,7 +6,6 @@ package gc ...@@ -6,7 +6,6 @@ package gc
import ( import (
"cmd/compile/internal/types" "cmd/compile/internal/types"
"cmd/internal/src"
"fmt" "fmt"
) )
...@@ -18,7 +17,7 @@ func closurehdr(ntype *Node) { ...@@ -18,7 +17,7 @@ func closurehdr(ntype *Node) {
n.Func.Depth = funcdepth n.Func.Depth = funcdepth
n.Func.Outerfunc = Curfn n.Func.Outerfunc = Curfn
funchdr(n, src.NoPos) funchdr(n)
// steal ntype's argument names and // steal ntype's argument names and
// leave a fresh copy in their place. // leave a fresh copy in their place.
...@@ -59,7 +58,7 @@ func closurebody(body []*Node) *Node { ...@@ -59,7 +58,7 @@ func closurebody(body []*Node) *Node {
func_ := Curfn func_ := Curfn
func_.Nbody.Set(body) func_.Nbody.Set(body)
func_.Func.Endlineno = lineno func_.Func.Endlineno = lineno
funcbody(func_, src.NoPos) funcbody(func_)
// closure-specific variables are hanging off the // closure-specific variables are hanging off the
// ordinary ones in the symbol table; see oldname. // ordinary ones in the symbol table; see oldname.
...@@ -227,10 +226,8 @@ func makeclosure(func_ *Node) *Node { ...@@ -227,10 +226,8 @@ func makeclosure(func_ *Node) *Node {
} }
xfunc.Nbody.Set(func_.Nbody.Slice()) xfunc.Nbody.Set(func_.Nbody.Slice())
xfunc.Func.scopes = func_.Func.scopes
xfunc.Func.Dcl = append(func_.Func.Dcl, xfunc.Func.Dcl...) xfunc.Func.Dcl = append(func_.Func.Dcl, xfunc.Func.Dcl...)
func_.Func.Dcl = nil func_.Func.Dcl = nil
func_.Func.scopes.Scopes = nil
if xfunc.Nbody.Len() == 0 { if xfunc.Nbody.Len() == 0 {
Fatalf("empty body - won't generate any code") Fatalf("empty body - won't generate any code")
} }
...@@ -612,7 +609,6 @@ func makepartialcall(fn *Node, t0 *types.Type, meth *types.Sym) *Node { ...@@ -612,7 +609,6 @@ func makepartialcall(fn *Node, t0 *types.Type, meth *types.Sym) *Node {
xfunc.Func.Nname.Sym.SetExported(true) // disable export xfunc.Func.Nname.Sym.SetExported(true) // disable export
xfunc.Func.Nname.Name.Param.Ntype = xtype xfunc.Func.Nname.Name.Param.Ntype = xtype
xfunc.Func.Nname.Name.Defn = xfunc xfunc.Func.Nname.Name.Defn = xfunc
xfunc.Func.scopes.Scopes = []src.Scope{src.Scope{}}
declare(xfunc.Func.Nname, PFUNC) declare(xfunc.Func.Nname, PFUNC)
// Declare and initialize variable holding receiver. // Declare and initialize variable holding receiver.
......
...@@ -33,9 +33,6 @@ var block int32 // current block number ...@@ -33,9 +33,6 @@ var block int32 // current block number
// Sym definitions, and only a subset of its fields are actually used. // Sym definitions, and only a subset of its fields are actually used.
var dclstack *types.Sym var dclstack *types.Sym
// lastPopdclPos is the last pos passed to popdcl
var lastPopdclPos src.Pos
func dcopy(a, b *types.Sym) { func dcopy(a, b *types.Sym) {
a.Pkg = b.Pkg a.Pkg = b.Pkg
a.Name = b.Name a.Name = b.Name
...@@ -62,7 +59,7 @@ func pushdcl(s *types.Sym) *types.Sym { ...@@ -62,7 +59,7 @@ func pushdcl(s *types.Sym) *types.Sym {
// popdcl pops the innermost block scope and restores all symbol declarations // popdcl pops the innermost block scope and restores all symbol declarations
// to their previous state. // to their previous state.
func popdcl(pos src.Pos) { func popdcl() {
d := dclstack d := dclstack
for ; d != nil && d.Name != ""; d = d.Link { for ; d != nil && d.Name != ""; d = d.Link {
s := d.Pkg.Lookup(d.Name) s := d.Pkg.Lookup(d.Name)
...@@ -77,29 +74,16 @@ func popdcl(pos src.Pos) { ...@@ -77,29 +74,16 @@ func popdcl(pos src.Pos) {
dclstack = d.Link // pop mark dclstack = d.Link // pop mark
block = d.Block block = d.Block
if Curfn != nil {
Curfn.Func.scopes.Close(&Ctxt.PosTable, pos)
lastPopdclPos = pos
}
return
} }
// markdcl records the start of a new block scope for declarations. // markdcl records the start of a new block scope for declarations.
func markdcl(pos src.Pos) { func markdcl() {
d := push() d := push()
d.Name = "" // used as a mark in fifo d.Name = "" // used as a mark in fifo
d.Block = block d.Block = block
blockgen++ blockgen++
block = blockgen block = blockgen
if Curfn != nil {
Curfn.Func.scopes.Open(&Ctxt.PosTable, pos)
}
return
} }
// keep around for debugging // keep around for debugging
...@@ -467,14 +451,14 @@ func ifacedcl(n *Node) { ...@@ -467,14 +451,14 @@ func ifacedcl(n *Node) {
// and declare the arguments. // and declare the arguments.
// called in extern-declaration context // called in extern-declaration context
// returns in auto-declaration context. // returns in auto-declaration context.
func funchdr(n *Node, pos src.Pos) { func funchdr(n *Node) {
// change the declaration context from extern to auto // change the declaration context from extern to auto
if funcdepth == 0 && dclcontext != PEXTERN { if funcdepth == 0 && dclcontext != PEXTERN {
Fatalf("funchdr: dclcontext = %d", dclcontext) Fatalf("funchdr: dclcontext = %d", dclcontext)
} }
dclcontext = PAUTO dclcontext = PAUTO
funcstart(n, pos) funcstart(n)
if n.Func.Nname != nil { if n.Func.Nname != nil {
funcargs(n.Func.Nname.Name.Param.Ntype) funcargs(n.Func.Nname.Name.Param.Ntype)
...@@ -612,22 +596,22 @@ var funcdepth int32 // len(funcstack) during parsing, but then forced to be th ...@@ -612,22 +596,22 @@ var funcdepth int32 // len(funcstack) during parsing, but then forced to be th
// start the function. // start the function.
// called before funcargs; undone at end of funcbody. // called before funcargs; undone at end of funcbody.
func funcstart(n *Node, pos src.Pos) { func funcstart(n *Node) {
markdcl()
funcstack = append(funcstack, Curfn) funcstack = append(funcstack, Curfn)
funcdepth++ funcdepth++
Curfn = n Curfn = n
markdcl(pos)
} }
// finish the body. // finish the body.
// called in auto-declaration context. // called in auto-declaration context.
// returns in extern-declaration context. // returns in extern-declaration context.
func funcbody(n *Node, pos src.Pos) { func funcbody(n *Node) {
// change the declaration context from auto to extern // change the declaration context from auto to extern
if dclcontext != PAUTO { if dclcontext != PAUTO {
Fatalf("funcbody: unexpected dclcontext %d", dclcontext) Fatalf("funcbody: unexpected dclcontext %d", dclcontext)
} }
popdcl(pos) popdcl()
funcstack, Curfn = funcstack[:len(funcstack)-1], funcstack[len(funcstack)-1] funcstack, Curfn = funcstack[:len(funcstack)-1], funcstack[len(funcstack)-1]
funcdepth-- funcdepth--
if funcdepth == 0 { if funcdepth == 0 {
......
...@@ -4,10 +4,7 @@ ...@@ -4,10 +4,7 @@
package gc package gc
import ( import "cmd/compile/internal/types"
"cmd/compile/internal/types"
"cmd/internal/src"
)
// a function named init is a special case. // a function named init is a special case.
// it is called by the initialization before // it is called by the initialization before
...@@ -95,7 +92,7 @@ func fninit(n []*Node) { ...@@ -95,7 +92,7 @@ func fninit(n []*Node) {
fn.Func.Nname.Name.Defn = fn fn.Func.Nname.Name.Defn = fn
fn.Func.Nname.Name.Param.Ntype = nod(OTFUNC, nil, nil) fn.Func.Nname.Name.Param.Ntype = nod(OTFUNC, nil, nil)
declare(fn.Func.Nname, PFUNC) declare(fn.Func.Nname, PFUNC)
funchdr(fn, src.NoPos) funchdr(fn)
// (3) // (3)
a := nod(OIF, nil, nil) a := nod(OIF, nil, nil)
...@@ -155,7 +152,7 @@ func fninit(n []*Node) { ...@@ -155,7 +152,7 @@ func fninit(n []*Node) {
exportsym(fn.Func.Nname) exportsym(fn.Func.Nname)
fn.Nbody.Set(r) fn.Nbody.Set(r)
funcbody(fn, src.NoPos) funcbody(fn)
Curfn = fn Curfn = fn
fn = typecheck(fn, Etop) fn = typecheck(fn, Etop)
......
...@@ -326,7 +326,7 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) *Node { ...@@ -326,7 +326,7 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) *Node {
declare(f.Func.Nname, PFUNC) declare(f.Func.Nname, PFUNC)
} }
funchdr(f, fun.Pos()) funchdr(f)
if fun.Body != nil { if fun.Body != nil {
if f.Noescape() { if f.Noescape() {
...@@ -347,7 +347,7 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) *Node { ...@@ -347,7 +347,7 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) *Node {
} }
} }
funcbody(f, fun.Pos()) funcbody(f)
return f return f
} }
...@@ -777,14 +777,14 @@ func (p *noder) stmt(stmt syntax.Stmt) *Node { ...@@ -777,14 +777,14 @@ func (p *noder) stmt(stmt syntax.Stmt) *Node {
} }
func (p *noder) blockStmt(stmt *syntax.BlockStmt) []*Node { func (p *noder) blockStmt(stmt *syntax.BlockStmt) []*Node {
markdcl(stmt.Pos()) markdcl()
nodes := p.stmts(stmt.List) nodes := p.stmts(stmt.List)
popdcl(stmt.Rbrace) popdcl()
return nodes return nodes
} }
func (p *noder) ifStmt(stmt *syntax.IfStmt) *Node { func (p *noder) ifStmt(stmt *syntax.IfStmt) *Node {
markdcl(stmt.Pos()) markdcl()
n := p.nod(stmt, OIF, nil, nil) n := p.nod(stmt, OIF, nil, nil)
if stmt.Init != nil { if stmt.Init != nil {
n.Ninit.Set1(p.stmt(stmt.Init)) n.Ninit.Set1(p.stmt(stmt.Init))
...@@ -801,12 +801,12 @@ func (p *noder) ifStmt(stmt *syntax.IfStmt) *Node { ...@@ -801,12 +801,12 @@ func (p *noder) ifStmt(stmt *syntax.IfStmt) *Node {
n.Rlist.Set1(e) n.Rlist.Set1(e)
} }
} }
popdcl(lastPopdclPos) popdcl()
return n return n
} }
func (p *noder) forStmt(stmt *syntax.ForStmt) *Node { func (p *noder) forStmt(stmt *syntax.ForStmt) *Node {
markdcl(stmt.Pos()) markdcl()
var n *Node var n *Node
if r, ok := stmt.Init.(*syntax.RangeClause); ok { if r, ok := stmt.Init.(*syntax.RangeClause); ok {
if stmt.Cond != nil || stmt.Post != nil { if stmt.Cond != nil || stmt.Post != nil {
...@@ -835,12 +835,12 @@ func (p *noder) forStmt(stmt *syntax.ForStmt) *Node { ...@@ -835,12 +835,12 @@ func (p *noder) forStmt(stmt *syntax.ForStmt) *Node {
} }
} }
n.Nbody.Set(p.blockStmt(stmt.Body)) n.Nbody.Set(p.blockStmt(stmt.Body))
popdcl(stmt.Body.Rbrace) popdcl()
return n return n
} }
func (p *noder) switchStmt(stmt *syntax.SwitchStmt) *Node { func (p *noder) switchStmt(stmt *syntax.SwitchStmt) *Node {
markdcl(stmt.Pos()) markdcl()
n := p.nod(stmt, OSWITCH, nil, nil) n := p.nod(stmt, OSWITCH, nil, nil)
if stmt.Init != nil { if stmt.Init != nil {
n.Ninit.Set1(p.stmt(stmt.Init)) n.Ninit.Set1(p.stmt(stmt.Init))
...@@ -854,17 +854,17 @@ func (p *noder) switchStmt(stmt *syntax.SwitchStmt) *Node { ...@@ -854,17 +854,17 @@ func (p *noder) switchStmt(stmt *syntax.SwitchStmt) *Node {
tswitch = nil tswitch = nil
} }
n.List.Set(p.caseClauses(stmt.Body, tswitch, stmt.Rbrace)) n.List.Set(p.caseClauses(stmt.Body, tswitch))
popdcl(stmt.Rbrace) popdcl()
return n return n
} }
func (p *noder) caseClauses(clauses []*syntax.CaseClause, tswitch *Node, rbrace src.Pos) []*Node { func (p *noder) caseClauses(clauses []*syntax.CaseClause, tswitch *Node) []*Node {
var nodes []*Node var nodes []*Node
for i, clause := range clauses { for _, clause := range clauses {
p.lineno(clause) p.lineno(clause)
markdcl(clause.Pos()) markdcl()
n := p.nod(clause, OXCASE, nil, nil) n := p.nod(clause, OXCASE, nil, nil)
if clause.Cases != nil { if clause.Cases != nil {
n.List.Set(p.exprList(clause.Cases)) n.List.Set(p.exprList(clause.Cases))
...@@ -878,11 +878,7 @@ func (p *noder) caseClauses(clauses []*syntax.CaseClause, tswitch *Node, rbrace ...@@ -878,11 +878,7 @@ func (p *noder) caseClauses(clauses []*syntax.CaseClause, tswitch *Node, rbrace
} }
n.Xoffset = int64(block) n.Xoffset = int64(block)
n.Nbody.Set(p.stmts(clause.Body)) n.Nbody.Set(p.stmts(clause.Body))
if i+1 < len(clauses) { popdcl()
popdcl(clauses[i+1].Pos())
} else {
popdcl(rbrace)
}
nodes = append(nodes, n) nodes = append(nodes, n)
} }
return nodes return nodes
...@@ -890,26 +886,22 @@ func (p *noder) caseClauses(clauses []*syntax.CaseClause, tswitch *Node, rbrace ...@@ -890,26 +886,22 @@ func (p *noder) caseClauses(clauses []*syntax.CaseClause, tswitch *Node, rbrace
func (p *noder) selectStmt(stmt *syntax.SelectStmt) *Node { func (p *noder) selectStmt(stmt *syntax.SelectStmt) *Node {
n := p.nod(stmt, OSELECT, nil, nil) n := p.nod(stmt, OSELECT, nil, nil)
n.List.Set(p.commClauses(stmt.Body, stmt.Rbrace)) n.List.Set(p.commClauses(stmt.Body))
return n return n
} }
func (p *noder) commClauses(clauses []*syntax.CommClause, rbrace src.Pos) []*Node { func (p *noder) commClauses(clauses []*syntax.CommClause) []*Node {
var nodes []*Node var nodes []*Node
for i, clause := range clauses { for _, clause := range clauses {
p.lineno(clause) p.lineno(clause)
markdcl(clause.Pos()) markdcl()
n := p.nod(clause, OXCASE, nil, nil) n := p.nod(clause, OXCASE, nil, nil)
if clause.Comm != nil { if clause.Comm != nil {
n.List.Set1(p.stmt(clause.Comm)) n.List.Set1(p.stmt(clause.Comm))
} }
n.Xoffset = int64(block) n.Xoffset = int64(block)
n.Nbody.Set(p.stmts(clause.Body)) n.Nbody.Set(p.stmts(clause.Body))
if i+1 < len(clauses) { popdcl()
popdcl(clauses[i+1].Pos())
} else {
popdcl(rbrace)
}
nodes = append(nodes, n) nodes = append(nodes, n)
} }
return nodes return nodes
......
...@@ -310,18 +310,13 @@ func compile(fn *Node) { ...@@ -310,18 +310,13 @@ func compile(fn *Node) {
pp.Free() pp.Free()
} }
func debuginfo(fnsym *obj.LSym, curfn interface{}) []dwarf.Scope { func debuginfo(fnsym *obj.LSym, curfn interface{}) []*dwarf.Var {
fn := curfn.(*Node) fn := curfn.(*Node)
if expect := Linksym(fn.Func.Nname.Sym); fnsym != expect { if expect := Linksym(fn.Func.Nname.Sym); fnsym != expect {
Fatalf("unexpected fnsym: %v != %v", fnsym, expect) Fatalf("unexpected fnsym: %v != %v", fnsym, expect)
} }
scopes := make([]dwarf.Scope, len(fn.Func.scopes.Scopes)) var vars []*dwarf.Var
for i := range scopes {
scopes[i] = dwarf.Scope{Scope: fn.Func.scopes.Scopes[i]}
}
for _, n := range fn.Func.Dcl { for _, n := range fn.Func.Dcl {
if n.Op != ONAME { // might be OTYPE or OLITERAL if n.Op != ONAME { // might be OTYPE or OLITERAL
continue continue
...@@ -368,14 +363,8 @@ func debuginfo(fnsym *obj.LSym, curfn interface{}) []dwarf.Scope { ...@@ -368,14 +363,8 @@ func debuginfo(fnsym *obj.LSym, curfn interface{}) []dwarf.Scope {
continue continue
} }
var scope int32 = 0
// Only record scope information when inlining is disabled.
if Debug['l'] == 0 {
scope = findScope(n.Pos, scopes)
}
typename := dwarf.InfoPrefix + gotype.Name[len("type."):] typename := dwarf.InfoPrefix + gotype.Name[len("type."):]
scopes[scope].Vars = append(scopes[scope].Vars, &dwarf.Var{ vars = append(vars, &dwarf.Var{
Name: n.Sym.Name, Name: n.Sym.Name,
Abbrev: abbrev, Abbrev: abbrev,
Offset: int32(offs), Offset: int32(offs),
...@@ -384,13 +373,9 @@ func debuginfo(fnsym *obj.LSym, curfn interface{}) []dwarf.Scope { ...@@ -384,13 +373,9 @@ func debuginfo(fnsym *obj.LSym, curfn interface{}) []dwarf.Scope {
} }
// Stable sort so that ties are broken with declaration order. // Stable sort so that ties are broken with declaration order.
for i := range scopes { sort.Stable(dwarf.VarsByOffset(vars))
sort.Stable(dwarf.VarsByOffset(scopes[i].Vars))
}
scopeRanges(fnsym, scopes)
return scopes return vars
} }
// fieldtrack adds R_USEFIELD relocations to fnsym to record any // fieldtrack adds R_USEFIELD relocations to fnsym to record any
......
// Copyright 2017 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.
package gc
import (
"cmd/internal/dwarf"
"cmd/internal/obj"
"cmd/internal/src"
)
// findScope returns the most specific scope containing pos.
func findScope(pos src.XPos, scopes []dwarf.Scope) int32 {
if !pos.IsKnown() {
return 0
}
for i := len(scopes) - 1; i > 0; i-- {
if pos.After(scopes[i].Start) && pos.Before(scopes[i].End) {
return int32(i)
}
}
return 0
}
type scopedProg struct {
p *obj.Prog
scope int32
}
// scopeRanges calculates scope ranges for symbol fnsym.
func scopeRanges(fnsym *obj.LSym, scopes []dwarf.Scope) {
var sp []scopedProg
for p := fnsym.Text; p != nil; p = p.Link {
sp = append(sp, scopedProg{p, -1})
}
for scopeID := int32(len(scopes) - 1); scopeID >= 0; scopeID-- {
if scope := &scopes[scopeID]; scope.Start.IsKnown() && scope.End.IsKnown() {
scopeProgs(sp, scopeID, scope.Start, scope.End)
}
}
scopedProgsToRanges(sp, scopes, fnsym.Size)
// Propagate scope's pc ranges to parent
for i := len(scopes) - 1; i > 0; i-- {
cur := &scopes[i]
if scopes[i].Parent != 0 {
parent := &scopes[scopes[i].Parent]
parent.UnifyRanges(cur)
}
}
}
// scopeProgs marks all scopedProgs between start and end that don't already
// belong to a scope as belonging to scopeId.
func scopeProgs(sp []scopedProg, scopeId int32, start, end src.XPos) {
for i := range sp {
if sp[i].scope >= 0 {
continue
}
if pos := sp[i].p.Pos; pos.After(start) && pos.Before(end) {
sp[i].scope = scopeId
}
}
}
// scopedProgsToRanges scans sp and collects in the Ranges field of each
// scope the start and end instruction of the scope.
func scopedProgsToRanges(sp []scopedProg, scopes []dwarf.Scope, symSize int64) {
var curscope int32 = -1
for i := range sp {
if sp[i].scope == curscope {
continue
}
if curscope >= 0 {
curranges := scopes[curscope].Ranges
curranges[len(curranges)-1].End = sp[i].p.Pc
}
curscope = sp[i].scope
if curscope >= 0 {
scopes[curscope].Ranges = append(scopes[curscope].Ranges, dwarf.Range{Start: sp[i].p.Pc, End: -1})
}
}
if curscope >= 0 {
curranges := scopes[curscope].Ranges
curranges[len(curranges)-1].End = symSize
}
}
This diff is collapsed.
...@@ -22,7 +22,7 @@ func TestSizeof(t *testing.T) { ...@@ -22,7 +22,7 @@ func TestSizeof(t *testing.T) {
_32bit uintptr // size on 32bit platforms _32bit uintptr // size on 32bit platforms
_64bit uintptr // size on 64bit platforms _64bit uintptr // size on 64bit platforms
}{ }{
{Func{}, 112, 192}, {Func{}, 96, 160},
{Name{}, 36, 56}, {Name{}, 36, 56},
{Param{}, 28, 56}, {Param{}, 28, 56},
{Node{}, 84, 136}, {Node{}, 84, 136},
......
...@@ -1687,7 +1687,7 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym, iface ...@@ -1687,7 +1687,7 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym, iface
lineno = autogeneratedPos lineno = autogeneratedPos
dclcontext = PEXTERN dclcontext = PEXTERN
markdcl(src.NoPos) markdcl()
this := namedfield(".this", rcvr) this := namedfield(".this", rcvr)
this.Left.Name.Param.Ntype = this.Right this.Left.Name.Param.Ntype = this.Right
...@@ -1717,7 +1717,7 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym, iface ...@@ -1717,7 +1717,7 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym, iface
fn.Func.Nname.Name.Param.Ntype = t fn.Func.Nname.Name.Param.Ntype = t
fn.Func.Nname.Sym.SetExported(true) // prevent export; see closure.go fn.Func.Nname.Sym.SetExported(true) // prevent export; see closure.go
declare(fn.Func.Nname, PFUNC) declare(fn.Func.Nname, PFUNC)
funchdr(fn, src.NoPos) funchdr(fn)
// arg list // arg list
var args []*Node var args []*Node
...@@ -1782,9 +1782,9 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym, iface ...@@ -1782,9 +1782,9 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym, iface
dumplist("genwrapper body", fn.Nbody) dumplist("genwrapper body", fn.Nbody)
} }
funcbody(fn, src.NoPos) funcbody(fn)
Curfn = fn Curfn = fn
popdcl(src.NoPos) popdcl()
if debug_dclstack != 0 { if debug_dclstack != 0 {
testdclstack() testdclstack()
} }
......
...@@ -321,10 +321,9 @@ type Func struct { ...@@ -321,10 +321,9 @@ type Func struct {
Shortname *types.Sym Shortname *types.Sym
Enter Nodes // for example, allocate and initialize memory for escaping parameters Enter Nodes // for example, allocate and initialize memory for escaping parameters
Exit Nodes Exit Nodes
Cvars Nodes // closure params Cvars Nodes // closure params
Dcl []*Node // autodcl for this func/closure Dcl []*Node // autodcl for this func/closure
Inldcl Nodes // copy of dcl for use in inlining Inldcl Nodes // copy of dcl for use in inlining
scopes src.Scopes // lexical scopes of the function
Closgen int Closgen int
Outerfunc *Node // outer function (for closure) Outerfunc *Node // outer function (for closure)
FieldTrack map[*types.Sym]struct{} FieldTrack map[*types.Sym]struct{}
......
...@@ -7,7 +7,6 @@ package gc ...@@ -7,7 +7,6 @@ package gc
import ( import (
"cmd/compile/internal/types" "cmd/compile/internal/types"
"cmd/internal/obj" "cmd/internal/obj"
"cmd/internal/src"
"cmd/internal/sys" "cmd/internal/sys"
"fmt" "fmt"
"strings" "strings"
...@@ -3662,7 +3661,7 @@ func walkprintfunc(n *Node, init *Nodes) *Node { ...@@ -3662,7 +3661,7 @@ func walkprintfunc(n *Node, init *Nodes) *Node {
oldfn := Curfn oldfn := Curfn
Curfn = nil Curfn = nil
funchdr(fn, src.NoPos) funchdr(fn)
a = nod(n.Op, nil, nil) a = nod(n.Op, nil, nil)
a.List.Set(printargs) a.List.Set(printargs)
...@@ -3671,7 +3670,7 @@ func walkprintfunc(n *Node, init *Nodes) *Node { ...@@ -3671,7 +3670,7 @@ func walkprintfunc(n *Node, init *Nodes) *Node {
fn.Nbody.Set1(a) fn.Nbody.Set1(a)
funcbody(fn, src.NoPos) funcbody(fn)
fn = typecheck(fn, Etop) fn = typecheck(fn, Etop)
typecheckslice(fn.Nbody.Slice(), Etop) typecheckslice(fn.Nbody.Slice(), Etop)
......
...@@ -8,20 +8,14 @@ ...@@ -8,20 +8,14 @@
package dwarf package dwarf
import ( import (
"cmd/internal/src"
"errors"
"fmt" "fmt"
) )
// InfoPrefix is the prefix for all the symbols containing DWARF info entries. // InfoPrefix is the prefix for all the symbols containing DWARF info entries.
const InfoPrefix = "go.info." const InfoPrefix = "go.info."
// RangePrefix is the prefix for all the symbols containing DWARF range lists.
const RangePrefix = "go.range."
// Sym represents a symbol. // Sym represents a symbol.
type Sym interface { type Sym interface {
Len() int64
} }
// A Var represents a local variable or a function parameter. // A Var represents a local variable or a function parameter.
...@@ -32,63 +26,6 @@ type Var struct { ...@@ -32,63 +26,6 @@ type Var struct {
Type Sym Type Sym
} }
// A Scope represents a lexical scope, all variables contained in a scope
// will only be visible to instructions covered by the scope.
// Lexical scopes are contiguous in source files but can end up being
// compiled to discontiguous blocks of instructions in the executable, the
// Ranges field lists all the blocks of instructions that belong in this
// scope.
type Scope struct {
src.Scope
Ranges []Range
Vars []*Var
}
// A Range represents a half-open interval [Start, End).
type Range struct {
Start, End int64
}
// UnifyRanges merges the list of ranges of c into the list of ranges of s
func (s *Scope) UnifyRanges(c *Scope) {
out := make([]Range, 0, len(s.Ranges)+len(c.Ranges))
i, j := 0, 0
for {
var cur Range
if i < len(s.Ranges) && j < len(c.Ranges) {
if s.Ranges[i].Start < c.Ranges[j].Start {
cur = s.Ranges[i]
i++
} else {
cur = c.Ranges[j]
j++
}
} else if i < len(s.Ranges) {
cur = s.Ranges[i]
i++
} else if j < len(c.Ranges) {
cur = c.Ranges[j]
j++
} else {
break
}
if len(out) == 0 {
out = append(out, cur)
} else {
last := &out[len(out)-1]
if cur.Start > last.End {
out = append(out, cur)
} else if cur.End > last.End {
last.End = cur.End
}
}
}
s.Ranges = out
}
// A Context specifies how to add data to a Sym. // A Context specifies how to add data to a Sym.
type Context interface { type Context interface {
PtrSize() int PtrSize() int
...@@ -216,8 +153,6 @@ const ( ...@@ -216,8 +153,6 @@ const (
DW_ABRV_VARIABLE DW_ABRV_VARIABLE
DW_ABRV_AUTO DW_ABRV_AUTO
DW_ABRV_PARAM DW_ABRV_PARAM
DW_ABRV_LEXICAL_BLOCK_RANGES
DW_ABRV_LEXICAL_BLOCK_SIMPLE
DW_ABRV_STRUCTFIELD DW_ABRV_STRUCTFIELD
DW_ABRV_FUNCTYPEPARAM DW_ABRV_FUNCTYPEPARAM
DW_ABRV_DOTDOTDOT DW_ABRV_DOTDOTDOT
...@@ -308,25 +243,6 @@ var abbrevs = [DW_NABRV]dwAbbrev{ ...@@ -308,25 +243,6 @@ var abbrevs = [DW_NABRV]dwAbbrev{
}, },
}, },
/* LEXICAL_BLOCK_RANGES */
{
DW_TAG_lexical_block,
DW_CHILDREN_yes,
[]dwAttrForm{
{DW_AT_ranges, DW_FORM_data4}, // replace with DW_FORM_sec_offset in DWARFv4.
},
},
/* LEXICAL_BLOCK_SIMPLE */
{
DW_TAG_lexical_block,
DW_CHILDREN_yes,
[]dwAttrForm{
{DW_AT_low_pc, DW_FORM_addr},
{DW_AT_high_pc, DW_FORM_addr},
},
},
/* STRUCTFIELD */ /* STRUCTFIELD */
{ {
DW_TAG_member, DW_TAG_member,
...@@ -604,8 +520,8 @@ func putattr(ctxt Context, s Sym, abbrev int, form int, cls int, value int64, da ...@@ -604,8 +520,8 @@ func putattr(ctxt Context, s Sym, abbrev int, form int, cls int, value int64, da
ctxt.AddInt(s, 2, value) ctxt.AddInt(s, 2, value)
case DW_FORM_data4: // constant, {line,loclist,mac,rangelist}ptr case DW_FORM_data4: // constant, {line,loclist,mac,rangelist}ptr
if cls == DW_CLS_PTR { // DW_AT_stmt_list and DW_AT_ranges if cls == DW_CLS_PTR { // DW_AT_stmt_list
ctxt.AddSectionOffset(s, 4, data, value) ctxt.AddSectionOffset(s, 4, data, 0)
break break
} }
ctxt.AddInt(s, 4, value) ctxt.AddInt(s, 4, value)
...@@ -634,13 +550,15 @@ func putattr(ctxt Context, s Sym, abbrev int, form int, cls int, value int64, da ...@@ -634,13 +550,15 @@ func putattr(ctxt Context, s Sym, abbrev int, form int, cls int, value int64, da
ctxt.AddInt(s, 1, 0) ctxt.AddInt(s, 1, 0)
} }
// In DWARF 3 the ref_addr is always 32 bits, unless emitting a large // In DWARF 2 (which is what we claim to generate),
// the ref_addr is the same size as a normal address.
// In DWARF 3 it is always 32 bits, unless emitting a large
// (> 4 GB of debug info aka "64-bit") unit, which we don't implement. // (> 4 GB of debug info aka "64-bit") unit, which we don't implement.
case DW_FORM_ref_addr: // reference to a DIE in the .info section case DW_FORM_ref_addr: // reference to a DIE in the .info section
if data == nil { if data == nil {
return fmt.Errorf("dwarf: null reference in %d", abbrev) return fmt.Errorf("dwarf: null reference in %d", abbrev)
} else { } else {
ctxt.AddSectionOffset(s, 4, data, 0) ctxt.AddSectionOffset(s, ctxt.PtrSize(), data, 0)
} }
case DW_FORM_ref1, // reference within the compilation unit case DW_FORM_ref1, // reference within the compilation unit
...@@ -683,7 +601,7 @@ func HasChildren(die *DWDie) bool { ...@@ -683,7 +601,7 @@ func HasChildren(die *DWDie) bool {
// PutFunc writes a DIE for a function to s. // PutFunc writes a DIE for a function to s.
// It also writes child DIEs for each variable in vars. // It also writes child DIEs for each variable in vars.
func PutFunc(ctxt Context, s, ranges Sym, name string, external bool, startPC Sym, size int64, scopes []Scope) error { func PutFunc(ctxt Context, s Sym, name string, external bool, startPC Sym, size int64, vars []*Var) {
Uleb128put(ctxt, s, DW_ABRV_FUNCTION) Uleb128put(ctxt, s, DW_ABRV_FUNCTION)
putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_string, DW_CLS_STRING, int64(len(name)), name) putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_string, DW_CLS_STRING, int64(len(name)), name)
putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_addr, DW_CLS_ADDRESS, 0, startPC) putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_addr, DW_CLS_ADDRESS, 0, startPC)
...@@ -693,72 +611,29 @@ func PutFunc(ctxt Context, s, ranges Sym, name string, external bool, startPC Sy ...@@ -693,72 +611,29 @@ func PutFunc(ctxt Context, s, ranges Sym, name string, external bool, startPC Sy
ev = 1 ev = 1
} }
putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_flag, DW_CLS_FLAG, ev, 0) putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_flag, DW_CLS_FLAG, ev, 0)
if len(scopes) > 0 { names := make(map[string]bool)
var encbuf [20]byte var encbuf [20]byte
if putscope(ctxt, s, ranges, startPC, 0, scopes, encbuf[:0]) < int32(len(scopes)) { for _, v := range vars {
return errors.New("multiple toplevel scopes") var n string
} if names[v.Name] {
} n = fmt.Sprintf("%s#%d", v.Name, len(names))
} else {
Uleb128put(ctxt, s, 0) n = v.Name
return nil
}
func putvar(ctxt Context, s Sym, v *Var, encbuf []byte) {
n := v.Name
Uleb128put(ctxt, s, int64(v.Abbrev))
putattr(ctxt, s, v.Abbrev, DW_FORM_string, DW_CLS_STRING, int64(len(n)), n)
loc := append(encbuf[:0], DW_OP_call_frame_cfa)
if v.Offset != 0 {
loc = append(loc, DW_OP_consts)
loc = AppendSleb128(loc, int64(v.Offset))
loc = append(loc, DW_OP_plus)
}
putattr(ctxt, s, v.Abbrev, DW_FORM_block1, DW_CLS_BLOCK, int64(len(loc)), loc)
putattr(ctxt, s, v.Abbrev, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, v.Type)
}
func putscope(ctxt Context, s, ranges Sym, startPC Sym, curscope int32, scopes []Scope, encbuf []byte) int32 {
for _, v := range scopes[curscope].Vars {
putvar(ctxt, s, v, encbuf)
}
this := curscope
curscope++
for curscope < int32(len(scopes)) {
scope := scopes[curscope]
if scope.Parent != this {
return curscope
}
emptyscope := len(scope.Vars) == 0 || len(scope.Ranges) == 0
if !emptyscope {
if len(scope.Ranges) == 1 {
Uleb128put(ctxt, s, DW_ABRV_LEXICAL_BLOCK_SIMPLE)
putattr(ctxt, s, DW_ABRV_LEXICAL_BLOCK_SIMPLE, DW_FORM_addr, DW_CLS_ADDRESS, scope.Ranges[0].Start, startPC)
putattr(ctxt, s, DW_ABRV_LEXICAL_BLOCK_SIMPLE, DW_FORM_addr, DW_CLS_ADDRESS, scope.Ranges[0].End, startPC)
} else {
Uleb128put(ctxt, s, DW_ABRV_LEXICAL_BLOCK_RANGES)
putattr(ctxt, s, DW_ABRV_LEXICAL_BLOCK_RANGES, DW_FORM_data4, DW_CLS_PTR, ranges.Len(), ranges)
ctxt.AddAddress(ranges, nil, -1)
ctxt.AddAddress(ranges, startPC, 0)
for _, pcrange := range scope.Ranges {
ctxt.AddAddress(ranges, nil, pcrange.Start)
ctxt.AddAddress(ranges, nil, pcrange.End)
}
ctxt.AddAddress(ranges, nil, 0)
ctxt.AddAddress(ranges, nil, 0)
}
} }
names[n] = true
curscope = putscope(ctxt, s, ranges, startPC, curscope, scopes, encbuf)
Uleb128put(ctxt, s, int64(v.Abbrev))
if !emptyscope { putattr(ctxt, s, v.Abbrev, DW_FORM_string, DW_CLS_STRING, int64(len(n)), n)
Uleb128put(ctxt, s, 0) loc := append(encbuf[:0], DW_OP_call_frame_cfa)
if v.Offset != 0 {
loc = append(loc, DW_OP_consts)
loc = AppendSleb128(loc, int64(v.Offset))
loc = append(loc, DW_OP_plus)
} }
putattr(ctxt, s, v.Abbrev, DW_FORM_block1, DW_CLS_BLOCK, int64(len(loc)), loc)
putattr(ctxt, s, v.Abbrev, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, v.Type)
} }
return curscope Uleb128put(ctxt, s, 0)
} }
// VarsByOffset attaches the methods of sort.Interface to []*Var, // VarsByOffset attaches the methods of sort.Interface to []*Var,
......
...@@ -114,7 +114,7 @@ func (s *LSym) WriteInt(ctxt *Link, off int64, siz int, i int64) { ...@@ -114,7 +114,7 @@ func (s *LSym) WriteInt(ctxt *Link, off int64, siz int, i int64) {
// WriteAddr writes an address of size siz into s at offset off. // WriteAddr writes an address of size siz into s at offset off.
// rsym and roff specify the relocation for the address. // rsym and roff specify the relocation for the address.
func (s *LSym) WriteAddr(ctxt *Link, off int64, siz int, rsym *LSym, roff int64) { func (s *LSym) WriteAddr(ctxt *Link, off int64, siz int, rsym *LSym, roff int64) {
if siz != ctxt.Arch.PtrSize && siz != 4 { if siz != ctxt.Arch.PtrSize {
ctxt.Diag("WriteAddr: bad address size %d in %s", siz, s.Name) ctxt.Diag("WriteAddr: bad address size %d in %s", siz, s.Name)
} }
s.prepwrite(ctxt, off, siz) s.prepwrite(ctxt, off, siz)
......
...@@ -483,7 +483,6 @@ const ( ...@@ -483,7 +483,6 @@ const (
SHOSTOBJ SHOSTOBJ
SDWARFSECT SDWARFSECT
SDWARFINFO SDWARFINFO
SDWARFRANGE
SSUB = SymKind(1 << 8) SSUB = SymKind(1 << 8)
SMASK = SymKind(SSUB - 1) SMASK = SymKind(SSUB - 1)
SHIDDEN = SymKind(1 << 9) SHIDDEN = SymKind(1 << 9)
...@@ -740,7 +739,7 @@ type Link struct { ...@@ -740,7 +739,7 @@ type Link struct {
Armsize int32 Armsize int32
Pc int64 Pc int64
DiagFunc func(string, ...interface{}) DiagFunc func(string, ...interface{})
DebugInfo func(fn *LSym, curfn interface{}) []dwarf.Scope // if non-nil, curfn is a *gc.Node DebugInfo func(fn *LSym, curfn interface{}) []*dwarf.Var // if non-nil, curfn is a *gc.Node
Cursym *LSym Cursym *LSym
Version int Version int
Errors int Errors int
......
...@@ -542,14 +542,10 @@ func (c dwCtxt) SymValue(s dwarf.Sym) int64 { ...@@ -542,14 +542,10 @@ func (c dwCtxt) SymValue(s dwarf.Sym) int64 {
return 0 return 0
} }
func (c dwCtxt) AddAddress(s dwarf.Sym, data interface{}, value int64) { func (c dwCtxt) AddAddress(s dwarf.Sym, data interface{}, value int64) {
rsym := data.(*LSym)
ls := s.(*LSym) ls := s.(*LSym)
size := c.PtrSize() size := c.PtrSize()
if data != nil { ls.WriteAddr(c.Link, ls.Size, size, rsym, value)
rsym := data.(*LSym)
ls.WriteAddr(c.Link, ls.Size, size, rsym, value)
} else {
ls.WriteInt(c.Link, ls.Size, size, value)
}
} }
func (c dwCtxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64) { func (c dwCtxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64) {
ls := s.(*LSym) ls := s.(*LSym)
...@@ -559,10 +555,6 @@ func (c dwCtxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64 ...@@ -559,10 +555,6 @@ func (c dwCtxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64
r.Type = R_DWARFREF r.Type = R_DWARFREF
} }
func (s *LSym) Len() int64 {
return s.Size
}
// makeFuncDebugEntry makes a DWARF Debugging Information Entry // makeFuncDebugEntry makes a DWARF Debugging Information Entry
// for TEXT symbol s. // for TEXT symbol s.
func makeFuncDebugEntry(ctxt *Link, curfn interface{}, s *LSym) { func makeFuncDebugEntry(ctxt *Link, curfn interface{}, s *LSym) {
...@@ -572,21 +564,10 @@ func makeFuncDebugEntry(ctxt *Link, curfn interface{}, s *LSym) { ...@@ -572,21 +564,10 @@ func makeFuncDebugEntry(ctxt *Link, curfn interface{}, s *LSym) {
} }
dsym.Type = SDWARFINFO dsym.Type = SDWARFINFO
dsym.Set(AttrDuplicateOK, s.DuplicateOK()) dsym.Set(AttrDuplicateOK, s.DuplicateOK())
var vars []*dwarf.Var
drsym := ctxt.Lookup(dwarf.RangePrefix+s.Name, int(s.Version))
if drsym.Size != 0 {
return
}
drsym.Type = SDWARFRANGE
drsym.Set(AttrDuplicateOK, s.DuplicateOK())
var scopes []dwarf.Scope
if ctxt.DebugInfo != nil { if ctxt.DebugInfo != nil {
scopes = ctxt.DebugInfo(s, curfn) vars = ctxt.DebugInfo(s, curfn)
}
err := dwarf.PutFunc(dwCtxt{ctxt}, dsym, drsym, s.Name, s.Version == 0, s, s.Size, scopes)
if err != nil {
ctxt.Diag("emitting DWARF for %s failed: %v", s.Name, err)
} }
ctxt.Data = append(ctxt.Data, dsym, drsym) dwarf.PutFunc(dwCtxt{ctxt}, dsym, s.Name, s.Version == 0, s, s.Size, vars)
ctxt.Data = append(ctxt.Data, dsym)
} }
// Copyright 2017 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.
package src
// Scope represents a lexical scope.
type Scope struct {
Start, End XPos
Parent int32
}
// Scopes represents a tree of lexical scopes
type Scopes struct {
Scopes []Scope // lexical scopes
curscope int32 // current scope index (during noding)
}
// Open starts a new scope, scopes.Curscope is the parent.
func (scopes *Scopes) Open(posTable *PosTable, pos Pos) {
scope := Scope{Parent: scopes.curscope, Start: NoXPos, End: NoXPos}
if pos.IsKnown() {
scope.Start = posTable.XPos(pos)
}
scopes.Scopes = append(scopes.Scopes, scope)
scopes.curscope = int32(len(scopes.Scopes) - 1)
}
// Close ends the current scope.
func (scopes *Scopes) Close(posTable *PosTable, pos Pos) {
scope := &scopes.Scopes[scopes.curscope]
if pos.IsKnown() {
scope.End = posTable.XPos(pos)
}
scopes.curscope = scope.Parent
}
...@@ -570,18 +570,9 @@ func relocsym(ctxt *Link, s *Symbol) { ...@@ -570,18 +570,9 @@ func relocsym(ctxt *Link, s *Symbol) {
} }
case obj.R_DWARFREF: case obj.R_DWARFREF:
sectName := "" if r.Sym.Sect == nil {
vaddr := int64(0)
if r.Sym.Sect != nil {
sectName = r.Sym.Sect.Name
vaddr = int64(r.Sym.Sect.Vaddr)
} else if r.Sym.Type == obj.SDWARFRANGE {
sectName = ".debug_ranges"
vaddr = 0
} else {
Errorf(s, "missing DWARF section for relocation target %s", r.Sym.Name) Errorf(s, "missing DWARF section for relocation target %s", r.Sym.Name)
} }
if Linkmode == LinkExternal { if Linkmode == LinkExternal {
r.Done = 0 r.Done = 0
// PE code emits IMAGE_REL_I386_SECREL and IMAGE_REL_AMD64_SECREL // PE code emits IMAGE_REL_I386_SECREL and IMAGE_REL_AMD64_SECREL
...@@ -593,9 +584,8 @@ func relocsym(ctxt *Link, s *Symbol) { ...@@ -593,9 +584,8 @@ func relocsym(ctxt *Link, s *Symbol) {
r.Type = obj.R_ADDR r.Type = obj.R_ADDR
} }
r.Xsym = ctxt.Syms.ROLookup(sectName, 0) r.Xsym = ctxt.Syms.ROLookup(r.Sym.Sect.Name, 0)
r.Xadd = r.Add + Symaddr(r.Sym) - vaddr r.Xadd = r.Add + Symaddr(r.Sym) - int64(r.Sym.Sect.Vaddr)
o = r.Xadd o = r.Xadd
rs = r.Xsym rs = r.Xsym
if Iself && SysArch.Family == sys.AMD64 { if Iself && SysArch.Family == sys.AMD64 {
...@@ -603,7 +593,7 @@ func relocsym(ctxt *Link, s *Symbol) { ...@@ -603,7 +593,7 @@ func relocsym(ctxt *Link, s *Symbol) {
} }
break break
} }
o = Symaddr(r.Sym) + r.Add - vaddr o = Symaddr(r.Sym) + r.Add - int64(r.Sym.Sect.Vaddr)
case obj.R_WEAKADDROFF: case obj.R_WEAKADDROFF:
if !r.Sym.Attr.Reachable() { if !r.Sym.Attr.Reachable() {
...@@ -1832,7 +1822,6 @@ func (ctxt *Link) dodata() { ...@@ -1832,7 +1822,6 @@ func (ctxt *Link) dodata() {
if s.Type != obj.SDWARFSECT { if s.Type != obj.SDWARFSECT {
break break
} }
sect = addsection(&Segdwarf, s.Name, 04) sect = addsection(&Segdwarf, s.Name, 04)
sect.Align = 1 sect.Align = 1
datsize = Rnd(datsize, int64(sect.Align)) datsize = Rnd(datsize, int64(sect.Align))
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
// - assign global variables and types to their packages // - assign global variables and types to their packages
// - gdb uses c syntax, meaning clumsy quoting is needed for go identifiers. eg // - gdb uses c syntax, meaning clumsy quoting is needed for go identifiers. eg
// ptype struct '[]uint8' and qualifiers need to be quoted away // ptype struct '[]uint8' and qualifiers need to be quoted away
// - lexical scoping is lost, so gdb gets confused as to which 'main.i' you mean.
// - file:line info for variables // - file:line info for variables
// - make strings a typedef so prettyprinters can see the underlying string type // - make strings a typedef so prettyprinters can see the underlying string type
...@@ -75,7 +76,6 @@ var arangessec *Symbol ...@@ -75,7 +76,6 @@ var arangessec *Symbol
var framesec *Symbol var framesec *Symbol
var infosec *Symbol var infosec *Symbol
var linesec *Symbol var linesec *Symbol
var rangesec *Symbol
var gdbscript string var gdbscript string
...@@ -1288,34 +1288,6 @@ func writeframes(ctxt *Link, syms []*Symbol) []*Symbol { ...@@ -1288,34 +1288,6 @@ func writeframes(ctxt *Link, syms []*Symbol) []*Symbol {
return syms return syms
} }
func writeranges(ctxt *Link, syms []*Symbol) []*Symbol {
if rangesec == nil {
rangesec = ctxt.Syms.Lookup(".debug_ranges", 0)
}
rangesec.Type = obj.SDWARFSECT
rangesec.Attr |= AttrReachable
rangesec.R = rangesec.R[:0]
for _, s := range ctxt.Textp {
rangeSym := ctxt.Syms.Lookup(dwarf.RangePrefix+s.Name, int(s.Version))
rangeSym.Attr |= AttrHidden
rangeSym.Attr |= AttrReachable
rangeSym.Type = obj.SDWARFRANGE
rangeSym.Value = rangesec.Size
rangesec.P = append(rangesec.P, rangeSym.P...)
for _, r := range rangeSym.R {
r.Off += int32(rangesec.Size)
rangesec.R = append(rangesec.R, r)
}
rangesec.Size += rangeSym.Size
}
if rangesec.Size > 0 {
// PE does not like empty sections
syms = append(syms, rangesec)
}
return syms
}
/* /*
* Walk DWarfDebugInfoEntries, and emit .debug_info * Walk DWarfDebugInfoEntries, and emit .debug_info
*/ */
...@@ -1346,7 +1318,7 @@ func writeinfo(ctxt *Link, syms []*Symbol, funcs []*Symbol) []*Symbol { ...@@ -1346,7 +1318,7 @@ func writeinfo(ctxt *Link, syms []*Symbol, funcs []*Symbol) []*Symbol {
// Fields marked with (*) must be changed for 64-bit dwarf // Fields marked with (*) must be changed for 64-bit dwarf
// This must match COMPUNITHEADERSIZE above. // This must match COMPUNITHEADERSIZE above.
Adduint32(ctxt, s, 0) // unit_length (*), will be filled in later. Adduint32(ctxt, s, 0) // unit_length (*), will be filled in later.
Adduint16(ctxt, s, 3) // dwarf version (appendix F) Adduint16(ctxt, s, 2) // dwarf version (appendix F)
// debug_abbrev_offset (*) // debug_abbrev_offset (*)
adddwarfref(ctxt, s, abbrevsym, 4) adddwarfref(ctxt, s, abbrevsym, 4)
...@@ -1559,7 +1531,6 @@ func dwarfgeneratedebugsyms(ctxt *Link) { ...@@ -1559,7 +1531,6 @@ func dwarfgeneratedebugsyms(ctxt *Link) {
syms := writeabbrev(ctxt, nil) syms := writeabbrev(ctxt, nil)
syms, funcs := writelines(ctxt, syms) syms, funcs := writelines(ctxt, syms)
syms = writeframes(ctxt, syms) syms = writeframes(ctxt, syms)
syms = writeranges(ctxt, syms)
synthesizestringtypes(ctxt, dwtypes.Child) synthesizestringtypes(ctxt, dwtypes.Child)
synthesizeslicetypes(ctxt, dwtypes.Child) synthesizeslicetypes(ctxt, dwtypes.Child)
...@@ -1601,7 +1572,6 @@ func dwarfaddshstrings(ctxt *Link, shstrtab *Symbol) { ...@@ -1601,7 +1572,6 @@ func dwarfaddshstrings(ctxt *Link, shstrtab *Symbol) {
Addstring(shstrtab, ".debug_pubnames") Addstring(shstrtab, ".debug_pubnames")
Addstring(shstrtab, ".debug_pubtypes") Addstring(shstrtab, ".debug_pubtypes")
Addstring(shstrtab, ".debug_gdb_scripts") Addstring(shstrtab, ".debug_gdb_scripts")
Addstring(shstrtab, ".debug_ranges")
if Linkmode == LinkExternal { if Linkmode == LinkExternal {
Addstring(shstrtab, elfRelType+".debug_info") Addstring(shstrtab, elfRelType+".debug_info")
Addstring(shstrtab, elfRelType+".debug_aranges") Addstring(shstrtab, elfRelType+".debug_aranges")
...@@ -1629,10 +1599,6 @@ func dwarfaddelfsectionsyms(ctxt *Link) { ...@@ -1629,10 +1599,6 @@ func dwarfaddelfsectionsyms(ctxt *Link) {
putelfsectionsym(sym, sym.Sect.Elfsect.shnum) putelfsectionsym(sym, sym.Sect.Elfsect.shnum)
sym = ctxt.Syms.Lookup(".debug_frame", 0) sym = ctxt.Syms.Lookup(".debug_frame", 0)
putelfsectionsym(sym, sym.Sect.Elfsect.shnum) putelfsectionsym(sym, sym.Sect.Elfsect.shnum)
sym = ctxt.Syms.Lookup(".debug_ranges", 0)
if sym.Sect != nil {
putelfsectionsym(sym, sym.Sect.Elfsect.shnum)
}
} }
/* /*
......
...@@ -89,10 +89,6 @@ func (s *Symbol) ElfsymForReloc() int32 { ...@@ -89,10 +89,6 @@ func (s *Symbol) ElfsymForReloc() int32 {
} }
} }
func (s *Symbol) Len() int64 {
return s.Size
}
// Attribute is a set of common symbol attributes. // Attribute is a set of common symbol attributes.
type Attribute int16 type Attribute int16
......
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