Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
go
Commits
385cd668
Commit
385cd668
authored
Aug 11, 2017
by
Gerrit Code Review
Browse files
Options
Browse Files
Download
Plain Diff
Merge "Merge remote-tracking branch 'origin/dev.debug' into master"
parents
9aea0e89
6f6a9398
Changes
32
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
32 changed files
with
1551 additions
and
290 deletions
+1551
-290
src/cmd/compile/fmt_test.go
src/cmd/compile/fmt_test.go
+15
-0
src/cmd/compile/internal/gc/main.go
src/cmd/compile/internal/gc/main.go
+7
-1
src/cmd/compile/internal/gc/pgen.go
src/cmd/compile/internal/gc/pgen.go
+323
-34
src/cmd/compile/internal/gc/scope.go
src/cmd/compile/internal/gc/scope.go
+1
-1
src/cmd/compile/internal/gc/sizeof_test.go
src/cmd/compile/internal/gc/sizeof_test.go
+1
-1
src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/gc/ssa.go
+66
-39
src/cmd/compile/internal/gc/syntax.go
src/cmd/compile/internal/gc/syntax.go
+2
-0
src/cmd/compile/internal/ssa/cache.go
src/cmd/compile/internal/ssa/cache.go
+22
-0
src/cmd/compile/internal/ssa/debug.go
src/cmd/compile/internal/ssa/debug.go
+559
-0
src/cmd/compile/internal/ssa/decompose.go
src/cmd/compile/internal/ssa/decompose.go
+1
-0
src/cmd/compile/internal/ssa/export_test.go
src/cmd/compile/internal/ssa/export_test.go
+11
-11
src/cmd/compile/internal/ssa/gen/genericOps.go
src/cmd/compile/internal/ssa/gen/genericOps.go
+1
-0
src/cmd/compile/internal/ssa/html.go
src/cmd/compile/internal/ssa/html.go
+13
-0
src/cmd/compile/internal/ssa/location.go
src/cmd/compile/internal/ssa/location.go
+29
-3
src/cmd/compile/internal/ssa/opGen.go
src/cmd/compile/internal/ssa/opGen.go
+6
-0
src/cmd/compile/internal/ssa/regalloc.go
src/cmd/compile/internal/ssa/regalloc.go
+75
-23
src/cmd/compile/internal/ssa/sizeof_test.go
src/cmd/compile/internal/ssa/sizeof_test.go
+1
-0
src/cmd/compile/internal/ssa/stackalloc.go
src/cmd/compile/internal/ssa/stackalloc.go
+1
-1
src/cmd/compile/internal/ssa/value.go
src/cmd/compile/internal/ssa/value.go
+14
-1
src/cmd/internal/dwarf/dwarf.go
src/cmd/internal/dwarf/dwarf.go
+122
-37
src/cmd/internal/obj/link.go
src/cmd/internal/obj/link.go
+28
-25
src/cmd/internal/obj/objfile.go
src/cmd/internal/obj/objfile.go
+10
-7
src/cmd/internal/obj/plist.go
src/cmd/internal/obj/plist.go
+11
-7
src/cmd/internal/obj/x86/a.out.go
src/cmd/internal/obj/x86/a.out.go
+117
-0
src/cmd/internal/obj/x86/obj6.go
src/cmd/internal/obj/x86/obj6.go
+21
-18
src/cmd/internal/objabi/symkind.go
src/cmd/internal/objabi/symkind.go
+1
-0
src/cmd/internal/objabi/symkind_string.go
src/cmd/internal/objabi/symkind_string.go
+2
-2
src/cmd/link/internal/ld/data.go
src/cmd/link/internal/ld/data.go
+24
-19
src/cmd/link/internal/ld/dwarf.go
src/cmd/link/internal/ld/dwarf.go
+61
-53
src/cmd/link/internal/ld/elf.go
src/cmd/link/internal/ld/elf.go
+2
-5
src/cmd/link/internal/ld/symkind.go
src/cmd/link/internal/ld/symkind.go
+2
-0
src/cmd/link/internal/ld/symkind_string.go
src/cmd/link/internal/ld/symkind_string.go
+2
-2
No files found.
src/cmd/compile/fmt_test.go
View file @
385cd668
...
@@ -571,9 +571,16 @@ var knownFormats = map[string]string{
...
@@ -571,9 +571,16 @@ var knownFormats = map[string]string{
"*cmd/compile/internal/ssa.Block %s"
:
""
,
"*cmd/compile/internal/ssa.Block %s"
:
""
,
"*cmd/compile/internal/ssa.Block %v"
:
""
,
"*cmd/compile/internal/ssa.Block %v"
:
""
,
"*cmd/compile/internal/ssa.Func %s"
:
""
,
"*cmd/compile/internal/ssa.Func %s"
:
""
,
"*cmd/compile/internal/ssa.Func %v"
:
""
,
"*cmd/compile/internal/ssa.FuncDebug %v"
:
""
,
"*cmd/compile/internal/ssa.LocalSlot %+v"
:
""
,
"*cmd/compile/internal/ssa.LocalSlot %v"
:
""
,
"*cmd/compile/internal/ssa.Register %v"
:
""
,
"*cmd/compile/internal/ssa.SparseTreeNode %v"
:
""
,
"*cmd/compile/internal/ssa.SparseTreeNode %v"
:
""
,
"*cmd/compile/internal/ssa.Value %s"
:
""
,
"*cmd/compile/internal/ssa.Value %s"
:
""
,
"*cmd/compile/internal/ssa.Value %v"
:
""
,
"*cmd/compile/internal/ssa.Value %v"
:
""
,
"*cmd/compile/internal/ssa.VarLoc %+v"
:
""
,
"*cmd/compile/internal/ssa.VarLoc %v"
:
""
,
"*cmd/compile/internal/ssa.sparseTreeMapEntry %v"
:
""
,
"*cmd/compile/internal/ssa.sparseTreeMapEntry %v"
:
""
,
"*cmd/compile/internal/types.Field %p"
:
""
,
"*cmd/compile/internal/types.Field %p"
:
""
,
"*cmd/compile/internal/types.Field %v"
:
""
,
"*cmd/compile/internal/types.Field %v"
:
""
,
...
@@ -592,6 +599,7 @@ var knownFormats = map[string]string{
...
@@ -592,6 +599,7 @@ var knownFormats = map[string]string{
"*cmd/compile/internal/types.Type %p"
:
""
,
"*cmd/compile/internal/types.Type %p"
:
""
,
"*cmd/compile/internal/types.Type %s"
:
""
,
"*cmd/compile/internal/types.Type %s"
:
""
,
"*cmd/compile/internal/types.Type %v"
:
""
,
"*cmd/compile/internal/types.Type %v"
:
""
,
"*cmd/internal/dwarf.Location %#v"
:
""
,
"*cmd/internal/obj.Addr %v"
:
""
,
"*cmd/internal/obj.Addr %v"
:
""
,
"*cmd/internal/obj.LSym %v"
:
""
,
"*cmd/internal/obj.LSym %v"
:
""
,
"*cmd/internal/obj.Prog %s"
:
""
,
"*cmd/internal/obj.Prog %s"
:
""
,
...
@@ -600,17 +608,21 @@ var knownFormats = map[string]string{
...
@@ -600,17 +608,21 @@ var knownFormats = map[string]string{
"[16]byte %x"
:
""
,
"[16]byte %x"
:
""
,
"[]*cmd/compile/internal/gc.Node %v"
:
""
,
"[]*cmd/compile/internal/gc.Node %v"
:
""
,
"[]*cmd/compile/internal/gc.Sig %#v"
:
""
,
"[]*cmd/compile/internal/gc.Sig %#v"
:
""
,
"[]*cmd/compile/internal/ssa.Block %+v"
:
""
,
"[]*cmd/compile/internal/ssa.Value %v"
:
""
,
"[]*cmd/compile/internal/ssa.Value %v"
:
""
,
"[][]cmd/compile/internal/ssa.SlotID %v"
:
""
,
"[]byte %s"
:
""
,
"[]byte %s"
:
""
,
"[]byte %x"
:
""
,
"[]byte %x"
:
""
,
"[]cmd/compile/internal/ssa.Edge %v"
:
""
,
"[]cmd/compile/internal/ssa.Edge %v"
:
""
,
"[]cmd/compile/internal/ssa.ID %v"
:
""
,
"[]cmd/compile/internal/ssa.ID %v"
:
""
,
"[]cmd/compile/internal/ssa.VarLocList %v"
:
""
,
"[]string %v"
:
""
,
"[]string %v"
:
""
,
"bool %v"
:
""
,
"bool %v"
:
""
,
"byte %08b"
:
""
,
"byte %08b"
:
""
,
"byte %c"
:
""
,
"byte %c"
:
""
,
"cmd/compile/internal/arm.shift %d"
:
""
,
"cmd/compile/internal/arm.shift %d"
:
""
,
"cmd/compile/internal/gc.Class %d"
:
""
,
"cmd/compile/internal/gc.Class %d"
:
""
,
"cmd/compile/internal/gc.Class %v"
:
""
,
"cmd/compile/internal/gc.Ctype %d"
:
""
,
"cmd/compile/internal/gc.Ctype %d"
:
""
,
"cmd/compile/internal/gc.Ctype %v"
:
""
,
"cmd/compile/internal/gc.Ctype %v"
:
""
,
"cmd/compile/internal/gc.Level %d"
:
""
,
"cmd/compile/internal/gc.Level %d"
:
""
,
...
@@ -630,11 +642,13 @@ var knownFormats = map[string]string{
...
@@ -630,11 +642,13 @@ var knownFormats = map[string]string{
"cmd/compile/internal/ssa.Edge %v"
:
""
,
"cmd/compile/internal/ssa.Edge %v"
:
""
,
"cmd/compile/internal/ssa.GCNode %v"
:
""
,
"cmd/compile/internal/ssa.GCNode %v"
:
""
,
"cmd/compile/internal/ssa.ID %d"
:
""
,
"cmd/compile/internal/ssa.ID %d"
:
""
,
"cmd/compile/internal/ssa.ID %v"
:
""
,
"cmd/compile/internal/ssa.LocalSlot %v"
:
""
,
"cmd/compile/internal/ssa.LocalSlot %v"
:
""
,
"cmd/compile/internal/ssa.Location %v"
:
""
,
"cmd/compile/internal/ssa.Location %v"
:
""
,
"cmd/compile/internal/ssa.Op %s"
:
""
,
"cmd/compile/internal/ssa.Op %s"
:
""
,
"cmd/compile/internal/ssa.Op %v"
:
""
,
"cmd/compile/internal/ssa.Op %v"
:
""
,
"cmd/compile/internal/ssa.ValAndOff %s"
:
""
,
"cmd/compile/internal/ssa.ValAndOff %s"
:
""
,
"cmd/compile/internal/ssa.VarLocList %v"
:
""
,
"cmd/compile/internal/ssa.rbrank %d"
:
""
,
"cmd/compile/internal/ssa.rbrank %d"
:
""
,
"cmd/compile/internal/ssa.regMask %d"
:
""
,
"cmd/compile/internal/ssa.regMask %d"
:
""
,
"cmd/compile/internal/ssa.register %d"
:
""
,
"cmd/compile/internal/ssa.register %d"
:
""
,
...
@@ -648,6 +662,7 @@ var knownFormats = map[string]string{
...
@@ -648,6 +662,7 @@ var knownFormats = map[string]string{
"cmd/compile/internal/types.EType %d"
:
""
,
"cmd/compile/internal/types.EType %d"
:
""
,
"cmd/compile/internal/types.EType %s"
:
""
,
"cmd/compile/internal/types.EType %s"
:
""
,
"cmd/compile/internal/types.EType %v"
:
""
,
"cmd/compile/internal/types.EType %v"
:
""
,
"cmd/internal/dwarf.Location %#v"
:
""
,
"cmd/internal/src.Pos %s"
:
""
,
"cmd/internal/src.Pos %s"
:
""
,
"cmd/internal/src.Pos %v"
:
""
,
"cmd/internal/src.Pos %v"
:
""
,
"error %v"
:
""
,
"error %v"
:
""
,
...
...
src/cmd/compile/internal/gc/main.go
View file @
385cd668
...
@@ -44,6 +44,7 @@ var (
...
@@ -44,6 +44,7 @@ var (
Debug_vlog
bool
Debug_vlog
bool
Debug_wb
int
Debug_wb
int
Debug_pctab
string
Debug_pctab
string
Debug_locationlist
int
)
)
// Debug arguments.
// Debug arguments.
...
@@ -69,6 +70,7 @@ var debugtab = []struct {
...
@@ -69,6 +70,7 @@ var debugtab = []struct {
{
"wb"
,
"print information about write barriers"
,
&
Debug_wb
},
{
"wb"
,
"print information about write barriers"
,
&
Debug_wb
},
{
"export"
,
"print export data"
,
&
Debug_export
},
{
"export"
,
"print export data"
,
&
Debug_export
},
{
"pctab"
,
"print named pc-value table"
,
&
Debug_pctab
},
{
"pctab"
,
"print named pc-value table"
,
&
Debug_pctab
},
{
"locationlists"
,
"print information about DWARF location list creation"
,
&
Debug_locationlist
},
}
}
const
debugHelpHeader
=
`usage: -d arg[,arg]* and arg is <key>[=<value>]
const
debugHelpHeader
=
`usage: -d arg[,arg]* and arg is <key>[=<value>]
...
@@ -192,6 +194,7 @@ func Main(archInit func(*Arch)) {
...
@@ -192,6 +194,7 @@ func Main(archInit func(*Arch)) {
flag
.
BoolVar
(
&
pure_go
,
"complete"
,
false
,
"compiling complete package (no C or assembly)"
)
flag
.
BoolVar
(
&
pure_go
,
"complete"
,
false
,
"compiling complete package (no C or assembly)"
)
flag
.
StringVar
(
&
debugstr
,
"d"
,
""
,
"print debug information about items in `list`; try -d help"
)
flag
.
StringVar
(
&
debugstr
,
"d"
,
""
,
"print debug information about items in `list`; try -d help"
)
flag
.
BoolVar
(
&
flagDWARF
,
"dwarf"
,
true
,
"generate DWARF symbols"
)
flag
.
BoolVar
(
&
flagDWARF
,
"dwarf"
,
true
,
"generate DWARF symbols"
)
flag
.
BoolVar
(
&
Ctxt
.
Flag_locationlists
,
"dwarflocationlists"
,
false
,
"add location lists to DWARF in optimized mode"
)
objabi
.
Flagcount
(
"e"
,
"no limit on number of errors reported"
,
&
Debug
[
'e'
])
objabi
.
Flagcount
(
"e"
,
"no limit on number of errors reported"
,
&
Debug
[
'e'
])
objabi
.
Flagcount
(
"f"
,
"debug stack frames"
,
&
Debug
[
'f'
])
objabi
.
Flagcount
(
"f"
,
"debug stack frames"
,
&
Debug
[
'f'
])
objabi
.
Flagcount
(
"h"
,
"halt on error"
,
&
Debug
[
'h'
])
objabi
.
Flagcount
(
"h"
,
"halt on error"
,
&
Debug
[
'h'
])
...
@@ -298,6 +301,9 @@ func Main(archInit func(*Arch)) {
...
@@ -298,6 +301,9 @@ func Main(archInit func(*Arch)) {
if
nBackendWorkers
>
1
&&
!
concurrentBackendAllowed
()
{
if
nBackendWorkers
>
1
&&
!
concurrentBackendAllowed
()
{
log
.
Fatalf
(
"cannot use concurrent backend compilation with provided flags; invoked as %v"
,
os
.
Args
)
log
.
Fatalf
(
"cannot use concurrent backend compilation with provided flags; invoked as %v"
,
os
.
Args
)
}
}
if
Ctxt
.
Flag_locationlists
&&
len
(
Ctxt
.
Arch
.
DWARFRegisters
)
==
0
{
log
.
Fatalf
(
"location lists requested but register mapping not available on %v"
,
Ctxt
.
Arch
.
Name
)
}
// parse -d argument
// parse -d argument
if
debugstr
!=
""
{
if
debugstr
!=
""
{
...
@@ -383,7 +389,7 @@ func Main(archInit func(*Arch)) {
...
@@ -383,7 +389,7 @@ func Main(archInit func(*Arch)) {
Debug
[
'l'
]
=
1
-
Debug
[
'l'
]
Debug
[
'l'
]
=
1
-
Debug
[
'l'
]
}
}
trackScopes
=
flagDWARF
&&
Debug
[
'l'
]
==
0
&&
Debug
[
'N'
]
!=
0
trackScopes
=
flagDWARF
&&
((
Debug
[
'l'
]
==
0
&&
Debug
[
'N'
]
!=
0
)
||
Ctxt
.
Flag_locationlists
)
Widthptr
=
thearch
.
LinkArch
.
PtrSize
Widthptr
=
thearch
.
LinkArch
.
PtrSize
Widthreg
=
thearch
.
LinkArch
.
RegSize
Widthreg
=
thearch
.
LinkArch
.
RegSize
...
...
src/cmd/compile/internal/gc/pgen.go
View file @
385cd668
This diff is collapsed.
Click to expand it.
src/cmd/compile/internal/gc/scope.go
View file @
385cd668
...
@@ -168,7 +168,7 @@ func (v varsByScopeAndOffset) Less(i, j int) bool {
...
@@ -168,7 +168,7 @@ func (v varsByScopeAndOffset) Less(i, j int) bool {
if
v
.
scopes
[
i
]
!=
v
.
scopes
[
j
]
{
if
v
.
scopes
[
i
]
!=
v
.
scopes
[
j
]
{
return
v
.
scopes
[
i
]
<
v
.
scopes
[
j
]
return
v
.
scopes
[
i
]
<
v
.
scopes
[
j
]
}
}
return
v
.
vars
[
i
]
.
Offset
<
v
.
vars
[
j
]
.
Offset
return
v
.
vars
[
i
]
.
StackOffset
<
v
.
vars
[
j
]
.
Stack
Offset
}
}
func
(
v
varsByScopeAndOffset
)
Swap
(
i
,
j
int
)
{
func
(
v
varsByScopeAndOffset
)
Swap
(
i
,
j
int
)
{
...
...
src/cmd/compile/internal/gc/sizeof_test.go
View file @
385cd668
...
@@ -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
{},
12
4
,
216
},
{
Func
{},
12
8
,
224
},
{
Name
{},
36
,
56
},
{
Name
{},
36
,
56
},
{
Param
{},
28
,
56
},
{
Param
{},
28
,
56
},
{
Node
{},
76
,
128
},
{
Node
{},
76
,
128
},
...
...
src/cmd/compile/internal/gc/ssa.go
View file @
385cd668
...
@@ -4401,14 +4401,15 @@ func genssa(f *ssa.Func, pp *Progs) {
...
@@ -4401,14 +4401,15 @@ func genssa(f *ssa.Func, pp *Progs) {
// Remember where each block starts.
// Remember where each block starts.
s
.
bstart
=
make
([]
*
obj
.
Prog
,
f
.
NumBlocks
())
s
.
bstart
=
make
([]
*
obj
.
Prog
,
f
.
NumBlocks
())
s
.
pp
=
pp
s
.
pp
=
pp
var
valueProgs
map
[
*
obj
.
Prog
]
*
ssa
.
Value
var
progToValue
map
[
*
obj
.
Prog
]
*
ssa
.
Value
var
blockProgs
map
[
*
obj
.
Prog
]
*
ssa
.
Block
var
progToBlock
map
[
*
obj
.
Prog
]
*
ssa
.
Block
var
valueToProg
[]
*
obj
.
Prog
var
logProgs
=
e
.
log
var
logProgs
=
e
.
log
if
logProgs
{
if
logProgs
{
valueProgs
=
make
(
map
[
*
obj
.
Prog
]
*
ssa
.
Value
,
f
.
NumValues
())
progToValue
=
make
(
map
[
*
obj
.
Prog
]
*
ssa
.
Value
,
f
.
NumValues
())
blockProgs
=
make
(
map
[
*
obj
.
Prog
]
*
ssa
.
Block
,
f
.
NumBlocks
())
progToBlock
=
make
(
map
[
*
obj
.
Prog
]
*
ssa
.
Block
,
f
.
NumBlocks
())
f
.
Logf
(
"genssa %s
\n
"
,
f
.
Name
)
f
.
Logf
(
"genssa %s
\n
"
,
f
.
Name
)
blockProgs
[
s
.
pp
.
next
]
=
f
.
Blocks
[
0
]
progToBlock
[
s
.
pp
.
next
]
=
f
.
Blocks
[
0
]
}
}
if
thearch
.
Use387
{
if
thearch
.
Use387
{
...
@@ -4417,6 +4418,11 @@ func genssa(f *ssa.Func, pp *Progs) {
...
@@ -4417,6 +4418,11 @@ func genssa(f *ssa.Func, pp *Progs) {
s
.
ScratchFpMem
=
e
.
scratchFpMem
s
.
ScratchFpMem
=
e
.
scratchFpMem
logLocationLists
:=
Debug_locationlist
!=
0
if
Ctxt
.
Flag_locationlists
{
e
.
curfn
.
Func
.
DebugInfo
=
ssa
.
BuildFuncDebug
(
f
,
logLocationLists
)
valueToProg
=
make
([]
*
obj
.
Prog
,
f
.
NumValues
())
}
// Emit basic blocks
// Emit basic blocks
for
i
,
b
:=
range
f
.
Blocks
{
for
i
,
b
:=
range
f
.
Blocks
{
s
.
bstart
[
b
.
ID
]
=
s
.
pp
.
next
s
.
bstart
[
b
.
ID
]
=
s
.
pp
.
next
...
@@ -4457,15 +4463,19 @@ func genssa(f *ssa.Func, pp *Progs) {
...
@@ -4457,15 +4463,19 @@ func genssa(f *ssa.Func, pp *Progs) {
}
}
case
ssa
.
OpPhi
:
case
ssa
.
OpPhi
:
CheckLoweredPhi
(
v
)
CheckLoweredPhi
(
v
)
case
ssa
.
OpRegKill
:
// nothing to do
default
:
default
:
// let the backend handle it
// let the backend handle it
thearch
.
SSAGenValue
(
&
s
,
v
)
thearch
.
SSAGenValue
(
&
s
,
v
)
}
}
if
Ctxt
.
Flag_locationlists
{
valueToProg
[
v
.
ID
]
=
x
}
if
logProgs
{
if
logProgs
{
for
;
x
!=
s
.
pp
.
next
;
x
=
x
.
Link
{
for
;
x
!=
s
.
pp
.
next
;
x
=
x
.
Link
{
valueProgs
[
x
]
=
v
progToValue
[
x
]
=
v
}
}
}
}
}
}
...
@@ -4483,7 +4493,23 @@ func genssa(f *ssa.Func, pp *Progs) {
...
@@ -4483,7 +4493,23 @@ func genssa(f *ssa.Func, pp *Progs) {
thearch
.
SSAGenBlock
(
&
s
,
b
,
next
)
thearch
.
SSAGenBlock
(
&
s
,
b
,
next
)
if
logProgs
{
if
logProgs
{
for
;
x
!=
s
.
pp
.
next
;
x
=
x
.
Link
{
for
;
x
!=
s
.
pp
.
next
;
x
=
x
.
Link
{
blockProgs
[
x
]
=
b
progToBlock
[
x
]
=
b
}
}
}
if
Ctxt
.
Flag_locationlists
{
for
_
,
locList
:=
range
e
.
curfn
.
Func
.
DebugInfo
.
Variables
{
for
_
,
loc
:=
range
locList
.
Locations
{
loc
.
StartProg
=
valueToProg
[
loc
.
Start
.
ID
]
if
loc
.
End
==
nil
{
Fatalf
(
"empty loc %v compiling %v"
,
loc
,
f
.
Name
)
}
loc
.
EndProg
=
valueToProg
[
loc
.
End
.
ID
]
if
!
logLocationLists
{
loc
.
Start
=
nil
loc
.
End
=
nil
}
}
}
}
}
}
}
...
@@ -4496,9 +4522,9 @@ func genssa(f *ssa.Func, pp *Progs) {
...
@@ -4496,9 +4522,9 @@ func genssa(f *ssa.Func, pp *Progs) {
if
logProgs
{
if
logProgs
{
for
p
:=
pp
.
Text
;
p
!=
nil
;
p
=
p
.
Link
{
for
p
:=
pp
.
Text
;
p
!=
nil
;
p
=
p
.
Link
{
var
s
string
var
s
string
if
v
,
ok
:=
valueProgs
[
p
];
ok
{
if
v
,
ok
:=
progToValue
[
p
];
ok
{
s
=
v
.
String
()
s
=
v
.
String
()
}
else
if
b
,
ok
:=
blockProgs
[
p
];
ok
{
}
else
if
b
,
ok
:=
progToBlock
[
p
];
ok
{
s
=
b
.
String
()
s
=
b
.
String
()
}
else
{
}
else
{
s
=
" "
// most value and branch strings are 2-3 characters long
s
=
" "
// most value and branch strings are 2-3 characters long
...
@@ -4516,9 +4542,9 @@ func genssa(f *ssa.Func, pp *Progs) {
...
@@ -4516,9 +4542,9 @@ func genssa(f *ssa.Func, pp *Progs) {
buf
.
WriteString
(
"<dl class=
\"
ssa-gen
\"
>"
)
buf
.
WriteString
(
"<dl class=
\"
ssa-gen
\"
>"
)
for
p
:=
pp
.
Text
;
p
!=
nil
;
p
=
p
.
Link
{
for
p
:=
pp
.
Text
;
p
!=
nil
;
p
=
p
.
Link
{
buf
.
WriteString
(
"<dt class=
\"
ssa-prog-src
\"
>"
)
buf
.
WriteString
(
"<dt class=
\"
ssa-prog-src
\"
>"
)
if
v
,
ok
:=
valueProgs
[
p
];
ok
{
if
v
,
ok
:=
progToValue
[
p
];
ok
{
buf
.
WriteString
(
v
.
HTML
())
buf
.
WriteString
(
v
.
HTML
())
}
else
if
b
,
ok
:=
blockProgs
[
p
];
ok
{
}
else
if
b
,
ok
:=
progToBlock
[
p
];
ok
{
buf
.
WriteString
(
b
.
HTML
())
buf
.
WriteString
(
b
.
HTML
())
}
}
buf
.
WriteString
(
"</dt>"
)
buf
.
WriteString
(
"</dt>"
)
...
@@ -4895,9 +4921,9 @@ func (e *ssafn) SplitString(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) {
...
@@ -4895,9 +4921,9 @@ func (e *ssafn) SplitString(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) {
lenType
:=
types
.
Types
[
TINT
]
lenType
:=
types
.
Types
[
TINT
]
if
n
.
Class
()
==
PAUTO
&&
!
n
.
Addrtaken
()
{
if
n
.
Class
()
==
PAUTO
&&
!
n
.
Addrtaken
()
{
// Split this string up into two separate variables.
// Split this string up into two separate variables.
p
:=
e
.
namedAuto
(
n
.
Sym
.
Name
+
".ptr"
,
ptrType
,
n
.
Pos
)
p
:=
e
.
splitSlot
(
&
name
,
".ptr"
,
0
,
ptrType
)
l
:=
e
.
namedAuto
(
n
.
Sym
.
Name
+
".len"
,
lenType
,
n
.
Pos
)
l
:=
e
.
splitSlot
(
&
name
,
".len"
,
ptrType
.
Size
(),
lenType
)
return
ssa
.
LocalSlot
{
N
:
p
,
Type
:
ptrType
,
Off
:
0
},
ssa
.
LocalSlot
{
N
:
l
,
Type
:
lenType
,
Off
:
0
}
return
p
,
l
}
}
// Return the two parts of the larger variable.
// Return the two parts of the larger variable.
return
ssa
.
LocalSlot
{
N
:
n
,
Type
:
ptrType
,
Off
:
name
.
Off
},
ssa
.
LocalSlot
{
N
:
n
,
Type
:
lenType
,
Off
:
name
.
Off
+
int64
(
Widthptr
)}
return
ssa
.
LocalSlot
{
N
:
n
,
Type
:
ptrType
,
Off
:
name
.
Off
},
ssa
.
LocalSlot
{
N
:
n
,
Type
:
lenType
,
Off
:
name
.
Off
+
int64
(
Widthptr
)}
...
@@ -4912,9 +4938,9 @@ func (e *ssafn) SplitInterface(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot
...
@@ -4912,9 +4938,9 @@ func (e *ssafn) SplitInterface(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot
if
n
.
Type
.
IsEmptyInterface
()
{
if
n
.
Type
.
IsEmptyInterface
()
{
f
=
".type"
f
=
".type"
}
}
c
:=
e
.
namedAuto
(
n
.
Sym
.
Name
+
f
,
t
,
n
.
Pos
)
c
:=
e
.
splitSlot
(
&
name
,
f
,
0
,
t
)
d
:=
e
.
namedAuto
(
n
.
Sym
.
Name
+
".data"
,
t
,
n
.
Pos
)
d
:=
e
.
splitSlot
(
&
name
,
".data"
,
t
.
Size
(),
t
)
return
ssa
.
LocalSlot
{
N
:
c
,
Type
:
t
,
Off
:
0
},
ssa
.
LocalSlot
{
N
:
d
,
Type
:
t
,
Off
:
0
}
return
c
,
d
}
}
// Return the two parts of the larger variable.
// Return the two parts of the larger variable.
return
ssa
.
LocalSlot
{
N
:
n
,
Type
:
t
,
Off
:
name
.
Off
},
ssa
.
LocalSlot
{
N
:
n
,
Type
:
t
,
Off
:
name
.
Off
+
int64
(
Widthptr
)}
return
ssa
.
LocalSlot
{
N
:
n
,
Type
:
t
,
Off
:
name
.
Off
},
ssa
.
LocalSlot
{
N
:
n
,
Type
:
t
,
Off
:
name
.
Off
+
int64
(
Widthptr
)}
...
@@ -4926,10 +4952,10 @@ func (e *ssafn) SplitSlice(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot, ss
...
@@ -4926,10 +4952,10 @@ func (e *ssafn) SplitSlice(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot, ss
lenType
:=
types
.
Types
[
TINT
]
lenType
:=
types
.
Types
[
TINT
]
if
n
.
Class
()
==
PAUTO
&&
!
n
.
Addrtaken
()
{
if
n
.
Class
()
==
PAUTO
&&
!
n
.
Addrtaken
()
{
// Split this slice up into three separate variables.
// Split this slice up into three separate variables.
p
:=
e
.
namedAuto
(
n
.
Sym
.
Name
+
".ptr"
,
ptrType
,
n
.
Pos
)
p
:=
e
.
splitSlot
(
&
name
,
".ptr"
,
0
,
ptrType
)
l
:=
e
.
namedAuto
(
n
.
Sym
.
Name
+
".len"
,
lenType
,
n
.
Pos
)
l
:=
e
.
splitSlot
(
&
name
,
".len"
,
ptrType
.
Size
(),
lenType
)
c
:=
e
.
namedAuto
(
n
.
Sym
.
Name
+
".cap"
,
lenType
,
n
.
Pos
)
c
:=
e
.
splitSlot
(
&
name
,
".cap"
,
ptrType
.
Size
()
+
lenType
.
Size
(),
lenType
)
return
ssa
.
LocalSlot
{
N
:
p
,
Type
:
ptrType
,
Off
:
0
},
ssa
.
LocalSlot
{
N
:
l
,
Type
:
lenType
,
Off
:
0
},
ssa
.
LocalSlot
{
N
:
c
,
Type
:
lenType
,
Off
:
0
}
return
p
,
l
,
c
}
}
// Return the three parts of the larger variable.
// Return the three parts of the larger variable.
return
ssa
.
LocalSlot
{
N
:
n
,
Type
:
ptrType
,
Off
:
name
.
Off
},
return
ssa
.
LocalSlot
{
N
:
n
,
Type
:
ptrType
,
Off
:
name
.
Off
},
...
@@ -4948,9 +4974,9 @@ func (e *ssafn) SplitComplex(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot)
...
@@ -4948,9 +4974,9 @@ func (e *ssafn) SplitComplex(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot)
}
}
if
n
.
Class
()
==
PAUTO
&&
!
n
.
Addrtaken
()
{
if
n
.
Class
()
==
PAUTO
&&
!
n
.
Addrtaken
()
{
// Split this complex up into two separate variables.
// Split this complex up into two separate variables.
c
:=
e
.
namedAuto
(
n
.
Sym
.
Name
+
".real"
,
t
,
n
.
Pos
)
r
:=
e
.
splitSlot
(
&
name
,
".real"
,
0
,
t
)
d
:=
e
.
namedAuto
(
n
.
Sym
.
Name
+
".imag"
,
t
,
n
.
Pos
)
i
:=
e
.
splitSlot
(
&
name
,
".imag"
,
t
.
Size
(),
t
)
return
ssa
.
LocalSlot
{
N
:
c
,
Type
:
t
,
Off
:
0
},
ssa
.
LocalSlot
{
N
:
d
,
Type
:
t
,
Off
:
0
}
return
r
,
i
}
}
// Return the two parts of the larger variable.
// Return the two parts of the larger variable.
return
ssa
.
LocalSlot
{
N
:
n
,
Type
:
t
,
Off
:
name
.
Off
},
ssa
.
LocalSlot
{
N
:
n
,
Type
:
t
,
Off
:
name
.
Off
+
s
}
return
ssa
.
LocalSlot
{
N
:
n
,
Type
:
t
,
Off
:
name
.
Off
},
ssa
.
LocalSlot
{
N
:
n
,
Type
:
t
,
Off
:
name
.
Off
+
s
}
...
@@ -4966,9 +4992,10 @@ func (e *ssafn) SplitInt64(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) {
...
@@ -4966,9 +4992,10 @@ func (e *ssafn) SplitInt64(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) {
}
}
if
n
.
Class
()
==
PAUTO
&&
!
n
.
Addrtaken
()
{
if
n
.
Class
()
==
PAUTO
&&
!
n
.
Addrtaken
()
{
// Split this int64 up into two separate variables.
// Split this int64 up into two separate variables.
h
:=
e
.
namedAuto
(
n
.
Sym
.
Name
+
".hi"
,
t
,
n
.
Pos
)
if
thearch
.
LinkArch
.
ByteOrder
==
binary
.
BigEndian
{
l
:=
e
.
namedAuto
(
n
.
Sym
.
Name
+
".lo"
,
types
.
Types
[
TUINT32
],
n
.
Pos
)
return
e
.
splitSlot
(
&
name
,
".hi"
,
0
,
t
),
e
.
splitSlot
(
&
name
,
".lo"
,
t
.
Size
(),
types
.
Types
[
TUINT32
])
return
ssa
.
LocalSlot
{
N
:
h
,
Type
:
t
,
Off
:
0
},
ssa
.
LocalSlot
{
N
:
l
,
Type
:
types
.
Types
[
TUINT32
],
Off
:
0
}
}
return
e
.
splitSlot
(
&
name
,
".hi"
,
t
.
Size
(),
t
),
e
.
splitSlot
(
&
name
,
".lo"
,
0
,
types
.
Types
[
TUINT32
])
}
}
// Return the two parts of the larger variable.
// Return the two parts of the larger variable.
if
thearch
.
LinkArch
.
ByteOrder
==
binary
.
BigEndian
{
if
thearch
.
LinkArch
.
ByteOrder
==
binary
.
BigEndian
{
...
@@ -4981,12 +5008,15 @@ func (e *ssafn) SplitStruct(name ssa.LocalSlot, i int) ssa.LocalSlot {
...
@@ -4981,12 +5008,15 @@ func (e *ssafn) SplitStruct(name ssa.LocalSlot, i int) ssa.LocalSlot {
n
:=
name
.
N
.
(
*
Node
)
n
:=
name
.
N
.
(
*
Node
)
st
:=
name
.
Type
st
:=
name
.
Type
ft
:=
st
.
FieldType
(
i
)
ft
:=
st
.
FieldType
(
i
)
var
offset
int64
for
f
:=
0
;
f
<
i
;
f
++
{
offset
+=
st
.
FieldType
(
f
)
.
Size
()
}
if
n
.
Class
()
==
PAUTO
&&
!
n
.
Addrtaken
()
{
if
n
.
Class
()
==
PAUTO
&&
!
n
.
Addrtaken
()
{
// Note: the _ field may appear several times. But
// Note: the _ field may appear several times. But
// have no fear, identically-named but distinct Autos are
// have no fear, identically-named but distinct Autos are
// ok, albeit maybe confusing for a debugger.
// ok, albeit maybe confusing for a debugger.
x
:=
e
.
namedAuto
(
n
.
Sym
.
Name
+
"."
+
st
.
FieldName
(
i
),
ft
,
n
.
Pos
)
return
e
.
splitSlot
(
&
name
,
"."
+
st
.
FieldName
(
i
),
offset
,
ft
)
return
ssa
.
LocalSlot
{
N
:
x
,
Type
:
ft
,
Off
:
0
}
}
}
return
ssa
.
LocalSlot
{
N
:
n
,
Type
:
ft
,
Off
:
name
.
Off
+
st
.
FieldOff
(
i
)}
return
ssa
.
LocalSlot
{
N
:
n
,
Type
:
ft
,
Off
:
name
.
Off
+
st
.
FieldOff
(
i
)}
}
}
...
@@ -4999,8 +5029,7 @@ func (e *ssafn) SplitArray(name ssa.LocalSlot) ssa.LocalSlot {
...
@@ -4999,8 +5029,7 @@ func (e *ssafn) SplitArray(name ssa.LocalSlot) ssa.LocalSlot {
}
}
et
:=
at
.
ElemType
()
et
:=
at
.
ElemType
()
if
n
.
Class
()
==
PAUTO
&&
!
n
.
Addrtaken
()
{
if
n
.
Class
()
==
PAUTO
&&
!
n
.
Addrtaken
()
{
x
:=
e
.
namedAuto
(
n
.
Sym
.
Name
+
"[0]"
,
et
,
n
.
Pos
)
return
e
.
splitSlot
(
&
name
,
"[0]"
,
0
,
et
)
return
ssa
.
LocalSlot
{
N
:
x
,
Type
:
et
,
Off
:
0
}
}
}
return
ssa
.
LocalSlot
{
N
:
n
,
Type
:
et
,
Off
:
name
.
Off
}
return
ssa
.
LocalSlot
{
N
:
n
,
Type
:
et
,
Off
:
name
.
Off
}
}
}
...
@@ -5009,16 +5038,14 @@ func (e *ssafn) DerefItab(it *obj.LSym, offset int64) *obj.LSym {
...
@@ -5009,16 +5038,14 @@ func (e *ssafn) DerefItab(it *obj.LSym, offset int64) *obj.LSym {
return
itabsym
(
it
,
offset
)
return
itabsym
(
it
,
offset
)
}
}
// namedAuto returns a new AUTO variable with the given name and type.
// splitSlot returns a slot representing the data of parent starting at offset.
// These are exposed to the debugger.
func
(
e
*
ssafn
)
splitSlot
(
parent
*
ssa
.
LocalSlot
,
suffix
string
,
offset
int64
,
t
*
types
.
Type
)
ssa
.
LocalSlot
{
func
(
e
*
ssafn
)
namedAuto
(
name
string
,
typ
*
types
.
Type
,
pos
src
.
XPos
)
ssa
.
GCNode
{
s
:=
&
types
.
Sym
{
Name
:
parent
.
N
.
(
*
Node
)
.
Sym
.
Name
+
suffix
,
Pkg
:
localpkg
}
t
:=
typ
s
:=
&
types
.
Sym
{
Name
:
name
,
Pkg
:
localpkg
}
n
:=
new
(
Node
)
n
:=
new
(
Node
)
n
.
Name
=
new
(
Name
)
n
.
Name
=
new
(
Name
)
n
.
Op
=
ONAME
n
.
Op
=
ONAME
n
.
Pos
=
pos
n
.
Pos
=
p
arent
.
N
.
(
*
Node
)
.
P
os
n
.
Orig
=
n
n
.
Orig
=
n
s
.
Def
=
asTypesNode
(
n
)
s
.
Def
=
asTypesNode
(
n
)
...
@@ -5031,7 +5058,7 @@ func (e *ssafn) namedAuto(name string, typ *types.Type, pos src.XPos) ssa.GCNode
...
@@ -5031,7 +5058,7 @@ func (e *ssafn) namedAuto(name string, typ *types.Type, pos src.XPos) ssa.GCNode
n
.
Name
.
Curfn
=
e
.
curfn
n
.
Name
.
Curfn
=
e
.
curfn
e
.
curfn
.
Func
.
Dcl
=
append
(
e
.
curfn
.
Func
.
Dcl
,
n
)
e
.
curfn
.
Func
.
Dcl
=
append
(
e
.
curfn
.
Func
.
Dcl
,
n
)
dowidth
(
t
)
dowidth
(
t
)
return
n
return
ssa
.
LocalSlot
{
N
:
n
,
Type
:
t
,
Off
:
0
,
SplitOf
:
parent
,
SplitOffset
:
offset
}
}
}
func
(
e
*
ssafn
)
CanSSA
(
t
*
types
.
Type
)
bool
{
func
(
e
*
ssafn
)
CanSSA
(
t
*
types
.
Type
)
bool
{
...
...
src/cmd/compile/internal/gc/syntax.go
View file @
385cd668
...
@@ -7,6 +7,7 @@
...
@@ -7,6 +7,7 @@
package
gc
package
gc
import
(
import
(
"cmd/compile/internal/ssa"
"cmd/compile/internal/syntax"
"cmd/compile/internal/syntax"
"cmd/compile/internal/types"
"cmd/compile/internal/types"
"cmd/internal/obj"
"cmd/internal/obj"
...
@@ -369,6 +370,7 @@ type Func struct {
...
@@ -369,6 +370,7 @@ type Func struct {
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
{}
DebugInfo
*
ssa
.
FuncDebug
Ntype
*
Node
// signature
Ntype
*
Node
// signature
Top
int
// top context (Ecall, Eproc, etc)
Top
int
// top context (Ecall, Eproc, etc)
Closure
*
Node
// OCLOSURE <-> ODCLFUNC
Closure
*
Node
// OCLOSURE <-> ODCLFUNC
...
...
src/cmd/compile/internal/ssa/cache.go
View file @
385cd668
...
@@ -14,6 +14,11 @@ type Cache struct {
...
@@ -14,6 +14,11 @@ type Cache struct {
blocks
[
200
]
Block
blocks
[
200
]
Block
locs
[
2000
]
Location
locs
[
2000
]
Location
// Storage for DWARF variable locations. Lazily allocated
// since location lists are off by default.
varLocs
[]
VarLoc
curVarLoc
int
// Reusable stackAllocState.
// Reusable stackAllocState.
// See stackalloc.go's {new,put}StackAllocState.
// See stackalloc.go's {new,put}StackAllocState.
stackAllocState
*
stackAllocState
stackAllocState
*
stackAllocState
...
@@ -38,4 +43,21 @@ func (c *Cache) Reset() {
...
@@ -38,4 +43,21 @@ func (c *Cache) Reset() {
for
i
:=
range
xl
{
for
i
:=
range
xl
{
xl
[
i
]
=
nil
xl
[
i
]
=
nil
}
}
xvl
:=
c
.
varLocs
[
:
c
.
curVarLoc
]
for
i
:=
range
xvl
{
xvl
[
i
]
=
VarLoc
{}
}
c
.
curVarLoc
=
0
}
func
(
c
*
Cache
)
NewVarLoc
()
*
VarLoc
{
if
c
.
varLocs
==
nil
{
c
.
varLocs
=
make
([]
VarLoc
,
4000
)
}
if
c
.
curVarLoc
==
len
(
c
.
varLocs
)
{
return
&
VarLoc
{}
}
vl
:=
&
c
.
varLocs
[
c
.
curVarLoc
]
c
.
curVarLoc
++
return
vl
}
}
src/cmd/compile/internal/ssa/debug.go
0 → 100644
View file @
385cd668
This diff is collapsed.
Click to expand it.
src/cmd/compile/internal/ssa/decompose.go
View file @
385cd668
...
@@ -98,6 +98,7 @@ func decomposeBuiltIn(f *Func) {
...
@@ -98,6 +98,7 @@ func decomposeBuiltIn(f *Func) {
delete
(
f
.
NamedValues
,
name
)
delete
(
f
.
NamedValues
,
name
)
case
t
.
IsFloat
()
:
case
t
.
IsFloat
()
:
// floats are never decomposed, even ones bigger than RegSize
// floats are never decomposed, even ones bigger than RegSize
newNames
=
append
(
newNames
,
name
)
case
t
.
Size
()
>
f
.
Config
.
RegSize
:
case
t
.
Size
()
>
f
.
Config
.
RegSize
:
f
.
Fatalf
(
"undecomposed named type %v %v"
,
name
,
t
)
f
.
Fatalf
(
"undecomposed named type %v %v"
,
name
,
t
)
default
:
default
:
...
...
src/cmd/compile/internal/ssa/export_test.go
View file @
385cd668
...
@@ -82,33 +82,33 @@ func (DummyFrontend) Auto(pos src.XPos, t *types.Type) GCNode {
...
@@ -82,33 +82,33 @@ func (DummyFrontend) Auto(pos src.XPos, t *types.Type) GCNode {
return
&
DummyAuto
{
t
:
t
,
s
:
"aDummyAuto"
}
return
&
DummyAuto
{
t
:
t
,
s
:
"aDummyAuto"
}
}
}
func
(
d
DummyFrontend
)
SplitString
(
s
LocalSlot
)
(
LocalSlot
,
LocalSlot
)
{
func
(
d
DummyFrontend
)
SplitString
(
s
LocalSlot
)
(
LocalSlot
,
LocalSlot
)
{
return
LocalSlot
{
s
.
N
,
dummyTypes
.
BytePtr
,
s
.
Off
},
LocalSlot
{
s
.
N
,
dummyTypes
.
Int
,
s
.
Off
+
8
}
return
LocalSlot
{
N
:
s
.
N
,
Type
:
dummyTypes
.
BytePtr
,
Off
:
s
.
Off
},
LocalSlot
{
N
:
s
.
N
,
Type
:
dummyTypes
.
Int
,
Off
:
s
.
Off
+
8
}
}
}
func
(
d
DummyFrontend
)
SplitInterface
(
s
LocalSlot
)
(
LocalSlot
,
LocalSlot
)
{
func
(
d
DummyFrontend
)
SplitInterface
(
s
LocalSlot
)
(
LocalSlot
,
LocalSlot
)
{
return
LocalSlot
{
s
.
N
,
dummyTypes
.
BytePtr
,
s
.
Off
},
LocalSlot
{
s
.
N
,
dummyTypes
.
BytePtr
,
s
.
Off
+
8
}
return
LocalSlot
{
N
:
s
.
N
,
Type
:
dummyTypes
.
BytePtr
,
Off
:
s
.
Off
},
LocalSlot
{
N
:
s
.
N
,
Type
:
dummyTypes
.
BytePtr
,
Off
:
s
.
Off
+
8
}
}
}
func
(
d
DummyFrontend
)
SplitSlice
(
s
LocalSlot
)
(
LocalSlot
,
LocalSlot
,
LocalSlot
)
{
func
(
d
DummyFrontend
)
SplitSlice
(
s
LocalSlot
)
(
LocalSlot
,
LocalSlot
,
LocalSlot
)
{
return
LocalSlot
{
s
.
N
,
s
.
Type
.
ElemType
()
.
PtrTo
(),
s
.
Off
},
return
LocalSlot
{
N
:
s
.
N
,
Type
:
s
.
Type
.
ElemType
()
.
PtrTo
(),
Off
:
s
.
Off
},
LocalSlot
{
s
.
N
,
dummyTypes
.
Int
,
s
.
Off
+
8
},
LocalSlot
{
N
:
s
.
N
,
Type
:
dummyTypes
.
Int
,
Off
:
s
.
Off
+
8
},
LocalSlot
{
s
.
N
,
dummyTypes
.
Int
,
s
.
Off
+
16
}
LocalSlot
{
N
:
s
.
N
,
Type
:
dummyTypes
.
Int
,
Off
:
s
.
Off
+
16
}
}
}
func
(
d
DummyFrontend
)
SplitComplex
(
s
LocalSlot
)
(
LocalSlot
,
LocalSlot
)
{
func
(
d
DummyFrontend
)
SplitComplex
(
s
LocalSlot
)
(
LocalSlot
,
LocalSlot
)
{
if
s
.
Type
.
Size
()
==
16
{
if
s
.
Type
.
Size
()
==
16
{
return
LocalSlot
{
s
.
N
,
dummyTypes
.
Float64
,
s
.
Off
},
LocalSlot
{
s
.
N
,
dummyTypes
.
Float64
,
s
.
Off
+
8
}
return
LocalSlot
{
N
:
s
.
N
,
Type
:
dummyTypes
.
Float64
,
Off
:
s
.
Off
},
LocalSlot
{
N
:
s
.
N
,
Type
:
dummyTypes
.
Float64
,
Off
:
s
.
Off
+
8
}
}
}
return
LocalSlot
{
s
.
N
,
dummyTypes
.
Float32
,
s
.
Off
},
LocalSlot
{
s
.
N
,
dummyTypes
.
Float32
,
s
.
Off
+
4
}
return
LocalSlot
{
N
:
s
.
N
,
Type
:
dummyTypes
.
Float32
,
Off
:
s
.
Off
},
LocalSlot
{
N
:
s
.
N
,
Type
:
dummyTypes
.
Float32
,
Off
:
s
.
Off
+
4
}
}
}
func
(
d
DummyFrontend
)
SplitInt64
(
s
LocalSlot
)
(
LocalSlot
,
LocalSlot
)
{
func
(
d
DummyFrontend
)
SplitInt64
(
s
LocalSlot
)
(
LocalSlot
,
LocalSlot
)
{
if
s
.
Type
.
IsSigned
()
{
if
s
.
Type
.
IsSigned
()
{
return
LocalSlot
{
s
.
N
,
dummyTypes
.
Int32
,
s
.
Off
+
4
},
LocalSlot
{
s
.
N
,
dummyTypes
.
UInt32
,
s
.
Off
}
return
LocalSlot
{
N
:
s
.
N
,
Type
:
dummyTypes
.
Int32
,
Off
:
s
.
Off
+
4
},
LocalSlot
{
N
:
s
.
N
,
Type
:
dummyTypes
.
UInt32
,
Off
:
s
.
Off
}
}
}
return
LocalSlot
{
s
.
N
,
dummyTypes
.
UInt32
,
s
.
Off
+
4
},
LocalSlot
{
s
.
N
,
dummyTypes
.
UInt32
,
s
.
Off
}
return
LocalSlot
{
N
:
s
.
N
,
Type
:
dummyTypes
.
UInt32
,
Off
:
s
.
Off
+
4
},
LocalSlot
{
N
:
s
.
N
,
Type
:
dummyTypes
.
UInt32
,
Off
:
s
.
Off
}
}
}
func
(
d
DummyFrontend
)
SplitStruct
(
s
LocalSlot
,
i
int
)
LocalSlot
{
func
(
d
DummyFrontend
)
SplitStruct
(
s
LocalSlot
,
i
int
)
LocalSlot
{
return
LocalSlot
{
s
.
N
,
s
.
Type
.
FieldType
(
i
),
s
.
Off
+
s
.
Type
.
FieldOff
(
i
)}
return
LocalSlot
{
N
:
s
.
N
,
Type
:
s
.
Type
.
FieldType
(
i
),
Off
:
s
.
Off
+
s
.
Type
.
FieldOff
(
i
)}
}
}
func
(
d
DummyFrontend
)
SplitArray
(
s
LocalSlot
)
LocalSlot
{
func
(
d
DummyFrontend
)
SplitArray
(
s
LocalSlot
)
LocalSlot
{
return
LocalSlot
{
s
.
N
,
s
.
Type
.
ElemType
(),
s
.
Off
}
return
LocalSlot
{
N
:
s
.
N
,
Type
:
s
.
Type
.
ElemType
(),
Off
:
s
.
Off
}
}
}
func
(
DummyFrontend
)
Line
(
_
src
.
XPos
)
string
{
func
(
DummyFrontend
)
Line
(
_
src
.
XPos
)
string
{
return
"unknown.go:0"
return
"unknown.go:0"
...
...
src/cmd/compile/internal/ssa/gen/genericOps.go
View file @
385cd668
...
@@ -420,6 +420,7 @@ var genericOps = []opData{
...
@@ -420,6 +420,7 @@ var genericOps = []opData{
{
name
:
"VarKill"
,
argLength
:
1
,
aux
:
"Sym"
,
symEffect
:
"None"
},
// aux is a *gc.Node of a variable that is known to be dead. arg0=mem, returns mem
{
name
:
"VarKill"
,
argLength
:
1
,
aux
:
"Sym"
,
symEffect
:
"None"
},
// aux is a *gc.Node of a variable that is known to be dead. arg0=mem, returns mem
{
name
:
"VarLive"
,
argLength
:
1
,
aux
:
"Sym"
,
symEffect
:
"None"
},
// aux is a *gc.Node of a variable that must be kept live. arg0=mem, returns mem
{
name
:
"VarLive"
,
argLength
:
1
,
aux
:
"Sym"
,
symEffect
:
"None"
},
// aux is a *gc.Node of a variable that must be kept live. arg0=mem, returns mem
{
name
:
"KeepAlive"
,
argLength
:
2
,
typ
:
"Mem"
},
// arg[0] is a value that must be kept alive until this mark. arg[1]=mem, returns mem
{
name
:
"KeepAlive"
,
argLength
:
2
,
typ
:
"Mem"
},
// arg[0] is a value that must be kept alive until this mark. arg[1]=mem, returns mem
{
name
:
"RegKill"
},
// regalloc has determined that the value in this register is dead
// Ops for breaking 64-bit operations on 32-bit architectures
// Ops for breaking 64-bit operations on 32-bit architectures
{
name
:
"Int64Make"
,
argLength
:
2
,
typ
:
"UInt64"
},
// arg0=hi, arg1=lo
{
name
:
"Int64Make"
,
argLength
:
2
,
typ
:
"UInt64"
},
// arg0=hi, arg1=lo
...
...
src/cmd/compile/internal/ssa/html.go
View file @
385cd668
...
@@ -11,6 +11,7 @@ import (
...
@@ -11,6 +11,7 @@ import (
"html"
"html"
"io"
"io"
"os"
"os"
"strings"
)
)
type
HTMLWriter
struct
{
type
HTMLWriter
struct
{
...
@@ -362,6 +363,18 @@ func (v *Value) LongHTML() string {
...
@@ -362,6 +363,18 @@ func (v *Value) LongHTML() string {
if
int
(
v
.
ID
)
<
len
(
r
)
&&
r
[
v
.
ID
]
!=
nil
{
if
int
(
v
.
ID
)
<
len
(
r
)
&&
r
[
v
.
ID
]
!=
nil
{
s
+=
" : "
+
html
.
EscapeString
(
r
[
v
.
ID
]
.
Name
())
s
+=
" : "
+
html
.
EscapeString
(
r
[
v
.
ID
]
.
Name
())
}
}
var
names
[]
string
for
name
,
values
:=
range
v
.
Block
.
Func
.
NamedValues
{
for
_
,
value
:=
range
values
{
if
value
==
v
{
names
=
append
(
names
,
name
.
Name
())
break
// drop duplicates.
}
}
}
if
len
(
names
)
!=
0
{
s
+=
" ("
+
strings
.
Join
(
names
,
", "
)
+
")"
}
s
+=
"</span>"
s
+=
"</span>"
return
s
return
s
}
}
...
...
src/cmd/compile/internal/ssa/location.go
View file @
385cd668
...
@@ -26,12 +26,38 @@ func (r *Register) Name() string {
...
@@ -26,12 +26,38 @@ func (r *Register) Name() string {
return
r
.
name
return
r
.
name
}
}
// A LocalSlot is a location in the stack frame.
// ObjNum returns the register number from cmd/internal/obj/$ARCH that
// It is (possibly a subpiece of) a PPARAM, PPARAMOUT, or PAUTO ONAME node.
// corresponds to this register.
func
(
r
*
Register
)
ObjNum
()
int16
{
return
r
.
objNum
}
// A LocalSlot is a location in the stack frame, which identifies and stores
// part or all of a PPARAM, PPARAMOUT, or PAUTO ONAME node.
// It can represent a whole variable, part of a larger stack slot, or part of a
// variable that has been decomposed into multiple stack slots.
// As an example, a string could have the following configurations:
//
// stack layout LocalSlots
//
// Optimizations are disabled. s is on the stack and represented in its entirety.
// [ ------- s string ---- ] { N: s, Type: string, Off: 0 }
//
// s was not decomposed, but the SSA operates on its parts individually, so
// there is a LocalSlot for each of its fields that points into the single stack slot.
// [ ------- s string ---- ] { N: s, Type: *uint8, Off: 0 }, {N: s, Type: int, Off: 8}
//
// s was decomposed. Each of its fields is in its own stack slot and has its own LocalSLot.
// [ ptr *uint8 ] [ len int] { N: ptr, Type: *uint8, Off: 0, SplitOf: parent, SplitOffset: 0},
// { N: len, Type: int, Off: 0, SplitOf: parent, SplitOffset: 8}
// parent = &{N: s, Type: string}
type
LocalSlot
struct
{
type
LocalSlot
struct
{
N
GCNode
// an ONAME *gc.Node representing a
variable on the stack
N
GCNode
// an ONAME *gc.Node representing a
stack location.
Type
*
types
.
Type
// type of slot
Type
*
types
.
Type
// type of slot
Off
int64
// offset of slot in N
Off
int64
// offset of slot in N
SplitOf
*
LocalSlot
// slot is a decomposition of SplitOf
SplitOffset
int64
// .. at this offset.
}
}
func
(
s
LocalSlot
)
Name
()
string
{
func
(
s
LocalSlot
)
Name
()
string
{
...
...
src/cmd/compile/internal/ssa/opGen.go
View file @
385cd668
...
@@ -1903,6 +1903,7 @@ const (
...
@@ -1903,6 +1903,7 @@ const (
OpVarKill
OpVarKill
OpVarLive
OpVarLive
OpKeepAlive
OpKeepAlive
OpRegKill
OpInt64Make
OpInt64Make
OpInt64Hi
OpInt64Hi
OpInt64Lo
OpInt64Lo
...
@@ -22557,6 +22558,11 @@ var opcodeTable = [...]opInfo{
...
@@ -22557,6 +22558,11 @@ var opcodeTable = [...]opInfo{
argLen
:
2
,
argLen
:
2
,
generic
:
true
,
generic
:
true
,
},
},
{
name
:
"RegKill"
,
argLen
:
0
,
generic
:
true
,
},
{
{
name
:
"Int64Make"
,
name
:
"Int64Make"
,
argLen
:
2
,
argLen
:
2
,
...
...
src/cmd/compile/internal/ssa/regalloc.go
View file @
385cd668
...
@@ -242,6 +242,9 @@ type regAllocState struct {
...
@@ -242,6 +242,9 @@ type regAllocState struct {
// current state of each (preregalloc) Value
// current state of each (preregalloc) Value
values
[]
valState
values
[]
valState
// names associated with each Value
valueNames
[][]
LocalSlot
// ID of SP, SB values
// ID of SP, SB values
sp
,
sb
ID
sp
,
sb
ID
...
@@ -300,6 +303,13 @@ type startReg struct {
...
@@ -300,6 +303,13 @@ type startReg struct {
// freeReg frees up register r. Any current user of r is kicked out.
// freeReg frees up register r. Any current user of r is kicked out.
func
(
s
*
regAllocState
)
freeReg
(
r
register
)
{
func
(
s
*
regAllocState
)
freeReg
(
r
register
)
{
s
.
freeOrResetReg
(
r
,
false
)
}
// freeOrResetReg frees up register r. Any current user of r is kicked out.
// resetting indicates that the operation is only for bookkeeping,
// e.g. when clearing out state upon entry to a new block.
func
(
s
*
regAllocState
)
freeOrResetReg
(
r
register
,
resetting
bool
)
{
v
:=
s
.
regs
[
r
]
.
v
v
:=
s
.
regs
[
r
]
.
v
if
v
==
nil
{
if
v
==
nil
{
s
.
f
.
Fatalf
(
"tried to free an already free register %d
\n
"
,
r
)
s
.
f
.
Fatalf
(
"tried to free an already free register %d
\n
"
,
r
)
...
@@ -309,6 +319,16 @@ func (s *regAllocState) freeReg(r register) {
...
@@ -309,6 +319,16 @@ func (s *regAllocState) freeReg(r register) {
if
s
.
f
.
pass
.
debug
>
regDebug
{
if
s
.
f
.
pass
.
debug
>
regDebug
{
fmt
.
Printf
(
"freeReg %s (dump %s/%s)
\n
"
,
s
.
registers
[
r
]
.
Name
(),
v
,
s
.
regs
[
r
]
.
c
)
fmt
.
Printf
(
"freeReg %s (dump %s/%s)
\n
"
,
s
.
registers
[
r
]
.
Name
(),
v
,
s
.
regs
[
r
]
.
c
)
}
}
if
!
resetting
&&
s
.
f
.
Config
.
ctxt
.
Flag_locationlists
&&
len
(
s
.
valueNames
[
v
.
ID
])
!=
0
{
kill
:=
s
.
curBlock
.
NewValue0
(
src
.
NoXPos
,
OpRegKill
,
types
.
TypeVoid
)
for
int
(
kill
.
ID
)
>=
len
(
s
.
orig
)
{
s
.
orig
=
append
(
s
.
orig
,
nil
)
}
for
_
,
name
:=
range
s
.
valueNames
[
v
.
ID
]
{
s
.
f
.
NamedValues
[
name
]
=
append
(
s
.
f
.
NamedValues
[
name
],
kill
)
}
s
.
f
.
setHome
(
kill
,
&
s
.
registers
[
r
])
}
s
.
regs
[
r
]
=
regState
{}
s
.
regs
[
r
]
=
regState
{}
s
.
values
[
v
.
ID
]
.
regs
&^=
regMask
(
1
)
<<
r
s
.
values
[
v
.
ID
]
.
regs
&^=
regMask
(
1
)
<<
r
s
.
used
&^=
regMask
(
1
)
<<
r
s
.
used
&^=
regMask
(
1
)
<<
r
...
@@ -599,6 +619,17 @@ func (s *regAllocState) init(f *Func) {
...
@@ -599,6 +619,17 @@ func (s *regAllocState) init(f *Func) {
s
.
values
=
make
([]
valState
,
f
.
NumValues
())
s
.
values
=
make
([]
valState
,
f
.
NumValues
())
s
.
orig
=
make
([]
*
Value
,
f
.
NumValues
())
s
.
orig
=
make
([]
*
Value
,
f
.
NumValues
())
s
.
copies
=
make
(
map
[
*
Value
]
bool
)
s
.
copies
=
make
(
map
[
*
Value
]
bool
)
if
s
.
f
.
Config
.
ctxt
.
Flag_locationlists
{
s
.
valueNames
=
make
([][]
LocalSlot
,
f
.
NumValues
())
for
slot
,
values
:=
range
f
.
NamedValues
{
if
isSynthetic
(
&
slot
)
{
continue
}
for
_
,
value
:=
range
values
{
s
.
valueNames
[
value
.
ID
]
=
append
(
s
.
valueNames
[
value
.
ID
],
slot
)
}
}
}
for
_
,
b
:=
range
f
.
Blocks
{
for
_
,
b
:=
range
f
.
Blocks
{
for
_
,
v
:=
range
b
.
Values
{
for
_
,
v
:=
range
b
.
Values
{
if
!
v
.
Type
.
IsMemory
()
&&
!
v
.
Type
.
IsVoid
()
&&
!
v
.
Type
.
IsFlags
()
&&
!
v
.
Type
.
IsTuple
()
{
if
!
v
.
Type
.
IsMemory
()
&&
!
v
.
Type
.
IsVoid
()
&&
!
v
.
Type
.
IsFlags
()
&&
!
v
.
Type
.
IsTuple
()
{
...
@@ -692,7 +723,9 @@ func (s *regAllocState) liveAfterCurrentInstruction(v *Value) bool {
...
@@ -692,7 +723,9 @@ func (s *regAllocState) liveAfterCurrentInstruction(v *Value) bool {
// Sets the state of the registers to that encoded in regs.
// Sets the state of the registers to that encoded in regs.
func
(
s
*
regAllocState
)
setState
(
regs
[]
endReg
)
{
func
(
s
*
regAllocState
)
setState
(
regs
[]
endReg
)
{
s
.
freeRegs
(
s
.
used
)
for
s
.
used
!=
0
{
s
.
freeOrResetReg
(
pickReg
(
s
.
used
),
true
)
}
for
_
,
x
:=
range
regs
{
for
_
,
x
:=
range
regs
{
s
.
assignReg
(
x
.
r
,
x
.
v
,
x
.
c
)
s
.
assignReg
(
x
.
r
,
x
.
v
,
x
.
c
)
}
}
...
@@ -735,6 +768,9 @@ func (s *regAllocState) regalloc(f *Func) {
...
@@ -735,6 +768,9 @@ func (s *regAllocState) regalloc(f *Func) {
}
}
for
_
,
b
:=
range
f
.
Blocks
{
for
_
,
b
:=
range
f
.
Blocks
{
if
s
.
f
.
pass
.
debug
>
regDebug
{
fmt
.
Printf
(
"Begin processing block %v
\n
"
,
b
)
}
s
.
curBlock
=
b
s
.
curBlock
=
b
// Initialize regValLiveSet and uses fields for this block.
// Initialize regValLiveSet and uses fields for this block.
...
@@ -830,9 +866,6 @@ func (s *regAllocState) regalloc(f *Func) {
...
@@ -830,9 +866,6 @@ func (s *regAllocState) regalloc(f *Func) {
// This is the complicated case. We have more than one predecessor,
// This is the complicated case. We have more than one predecessor,
// which means we may have Phi ops.
// which means we may have Phi ops.
// Copy phi ops into new schedule.
b
.
Values
=
append
(
b
.
Values
,
phis
...
)
// Start with the final register state of the primary predecessor
// Start with the final register state of the primary predecessor
idx
:=
s
.
primary
[
b
.
ID
]
idx
:=
s
.
primary
[
b
.
ID
]
if
idx
<
0
{
if
idx
<
0
{
...
@@ -910,6 +943,9 @@ func (s *regAllocState) regalloc(f *Func) {
...
@@ -910,6 +943,9 @@ func (s *regAllocState) regalloc(f *Func) {
}
}
}
}
// Copy phi ops into new schedule.
b
.
Values
=
append
(
b
.
Values
,
phis
...
)
// Third pass - pick registers for phis whose inputs
// Third pass - pick registers for phis whose inputs
// were not in a register.
// were not in a register.
for
i
,
v
:=
range
phis
{
for
i
,
v
:=
range
phis
{
...
@@ -1005,7 +1041,7 @@ func (s *regAllocState) regalloc(f *Func) {
...
@@ -1005,7 +1041,7 @@ func (s *regAllocState) regalloc(f *Func) {
pidx
:=
e
.
i
pidx
:=
e
.
i
for
_
,
v
:=
range
succ
.
Values
{
for
_
,
v
:=
range
succ
.
Values
{
if
v
.
Op
!=
OpPhi
{
if
v
.
Op
!=
OpPhi
{
break
continue
}
}
if
!
s
.
values
[
v
.
ID
]
.
needReg
{
if
!
s
.
values
[
v
.
ID
]
.
needReg
{
continue
continue
...
@@ -1565,6 +1601,9 @@ func (s *regAllocState) placeSpills() {
...
@@ -1565,6 +1601,9 @@ func (s *regAllocState) placeSpills() {
for
_
,
b
:=
range
f
.
Blocks
{
for
_
,
b
:=
range
f
.
Blocks
{
var
m
regMask
var
m
regMask
for
_
,
v
:=
range
b
.
Values
{
for
_
,
v
:=
range
b
.
Values
{
if
v
.
Op
==
OpRegKill
{
continue
}
if
v
.
Op
!=
OpPhi
{
if
v
.
Op
!=
OpPhi
{
break
break
}
}
...
@@ -1675,7 +1714,7 @@ func (s *regAllocState) placeSpills() {
...
@@ -1675,7 +1714,7 @@ func (s *regAllocState) placeSpills() {
for
_
,
b
:=
range
f
.
Blocks
{
for
_
,
b
:=
range
f
.
Blocks
{
nphi
:=
0
nphi
:=
0
for
_
,
v
:=
range
b
.
Values
{
for
_
,
v
:=
range
b
.
Values
{
if
v
.
Op
!=
OpPhi
{
if
v
.
Op
!=
Op
RegKill
&&
v
.
Op
!=
Op
Phi
{
break
break
}
}
nphi
++
nphi
++
...
@@ -1800,6 +1839,9 @@ func (e *edgeState) setup(idx int, srcReg []endReg, dstReg []startReg, stacklive
...
@@ -1800,6 +1839,9 @@ func (e *edgeState) setup(idx int, srcReg []endReg, dstReg []startReg, stacklive
}
}
// Phis need their args to end up in a specific location.
// Phis need their args to end up in a specific location.
for
_
,
v
:=
range
e
.
b
.
Values
{
for
_
,
v
:=
range
e
.
b
.
Values
{
if
v
.
Op
==
OpRegKill
{
continue
}
if
v
.
Op
!=
OpPhi
{
if
v
.
Op
!=
OpPhi
{
break
break
}
}
...
@@ -1878,6 +1920,7 @@ func (e *edgeState) process() {
...
@@ -1878,6 +1920,7 @@ func (e *edgeState) process() {
if
e
.
s
.
f
.
pass
.
debug
>
regDebug
{
if
e
.
s
.
f
.
pass
.
debug
>
regDebug
{
fmt
.
Printf
(
"breaking cycle with v%d in %s:%s
\n
"
,
vid
,
loc
.
Name
(),
c
)
fmt
.
Printf
(
"breaking cycle with v%d in %s:%s
\n
"
,
vid
,
loc
.
Name
(),
c
)
}
}
e
.
erase
(
r
)
if
_
,
isReg
:=
loc
.
(
*
Register
);
isReg
{
if
_
,
isReg
:=
loc
.
(
*
Register
);
isReg
{
c
=
e
.
p
.
NewValue1
(
d
.
pos
,
OpCopy
,
c
.
Type
,
c
)
c
=
e
.
p
.
NewValue1
(
d
.
pos
,
OpCopy
,
c
.
Type
,
c
)
}
else
{
}
else
{
...
@@ -1943,6 +1986,18 @@ func (e *edgeState) processDest(loc Location, vid ID, splice **Value, pos src.XP
...
@@ -1943,6 +1986,18 @@ func (e *edgeState) processDest(loc Location, vid ID, splice **Value, pos src.XP
}
}
}
}
_
,
dstReg
:=
loc
.
(
*
Register
)
_
,
dstReg
:=
loc
.
(
*
Register
)
// Pre-clobber destination. This avoids the
// following situation:
// - v is currently held in R0 and stacktmp0.
// - We want to copy stacktmp1 to stacktmp0.
// - We choose R0 as the temporary register.
// During the copy, both R0 and stacktmp0 are
// clobbered, losing both copies of v. Oops!
// Erasing the destination early means R0 will not
// be chosen as the temp register, as it will then
// be the last copy of v.
e
.
erase
(
loc
)
var
x
*
Value
var
x
*
Value
if
c
==
nil
{
if
c
==
nil
{
if
!
e
.
s
.
values
[
vid
]
.
rematerializeable
{
if
!
e
.
s
.
values
[
vid
]
.
rematerializeable
{
...
@@ -1953,8 +2008,8 @@ func (e *edgeState) processDest(loc Location, vid ID, splice **Value, pos src.XP
...
@@ -1953,8 +2008,8 @@ func (e *edgeState) processDest(loc Location, vid ID, splice **Value, pos src.XP
}
else
{
}
else
{
// Rematerialize into stack slot. Need a free
// Rematerialize into stack slot. Need a free
// register to accomplish this.
// register to accomplish this.
e
.
erase
(
loc
)
// see pre-clobber comment below
r
:=
e
.
findRegFor
(
v
.
Type
)
r
:=
e
.
findRegFor
(
v
.
Type
)
e
.
erase
(
r
)
x
=
v
.
copyIntoNoXPos
(
e
.
p
)
x
=
v
.
copyIntoNoXPos
(
e
.
p
)
e
.
set
(
r
,
vid
,
x
,
false
,
pos
)
e
.
set
(
r
,
vid
,
x
,
false
,
pos
)
// Make sure we spill with the size of the slot, not the
// Make sure we spill with the size of the slot, not the
...
@@ -1976,20 +2031,8 @@ func (e *edgeState) processDest(loc Location, vid ID, splice **Value, pos src.XP
...
@@ -1976,20 +2031,8 @@ func (e *edgeState) processDest(loc Location, vid ID, splice **Value, pos src.XP
x
=
e
.
p
.
NewValue1
(
pos
,
OpLoadReg
,
c
.
Type
,
c
)
x
=
e
.
p
.
NewValue1
(
pos
,
OpLoadReg
,
c
.
Type
,
c
)
}
else
{
}
else
{
// mem->mem. Use temp register.
// mem->mem. Use temp register.
// Pre-clobber destination. This avoids the
// following situation:
// - v is currently held in R0 and stacktmp0.
// - We want to copy stacktmp1 to stacktmp0.
// - We choose R0 as the temporary register.
// During the copy, both R0 and stacktmp0 are
// clobbered, losing both copies of v. Oops!
// Erasing the destination early means R0 will not
// be chosen as the temp register, as it will then
// be the last copy of v.
e
.
erase
(
loc
)
r
:=
e
.
findRegFor
(
c
.
Type
)
r
:=
e
.
findRegFor
(
c
.
Type
)
e
.
erase
(
r
)
t
:=
e
.
p
.
NewValue1
(
pos
,
OpLoadReg
,
c
.
Type
,
c
)
t
:=
e
.
p
.
NewValue1
(
pos
,
OpLoadReg
,
c
.
Type
,
c
)
e
.
set
(
r
,
vid
,
t
,
false
,
pos
)
e
.
set
(
r
,
vid
,
t
,
false
,
pos
)
x
=
e
.
p
.
NewValue1
(
pos
,
OpStoreReg
,
loc
.
(
LocalSlot
)
.
Type
,
t
)
x
=
e
.
p
.
NewValue1
(
pos
,
OpStoreReg
,
loc
.
(
LocalSlot
)
.
Type
,
t
)
...
@@ -2008,7 +2051,6 @@ func (e *edgeState) processDest(loc Location, vid ID, splice **Value, pos src.XP
...
@@ -2008,7 +2051,6 @@ func (e *edgeState) processDest(loc Location, vid ID, splice **Value, pos src.XP
// set changes the contents of location loc to hold the given value and its cached representative.
// set changes the contents of location loc to hold the given value and its cached representative.
func
(
e
*
edgeState
)
set
(
loc
Location
,
vid
ID
,
c
*
Value
,
final
bool
,
pos
src
.
XPos
)
{
func
(
e
*
edgeState
)
set
(
loc
Location
,
vid
ID
,
c
*
Value
,
final
bool
,
pos
src
.
XPos
)
{
e
.
s
.
f
.
setHome
(
c
,
loc
)
e
.
s
.
f
.
setHome
(
c
,
loc
)
e
.
erase
(
loc
)
e
.
contents
[
loc
]
=
contentRecord
{
vid
,
c
,
final
,
pos
}
e
.
contents
[
loc
]
=
contentRecord
{
vid
,
c
,
final
,
pos
}
a
:=
e
.
cache
[
vid
]
a
:=
e
.
cache
[
vid
]
if
len
(
a
)
==
0
{
if
len
(
a
)
==
0
{
...
@@ -2059,6 +2101,16 @@ func (e *edgeState) erase(loc Location) {
...
@@ -2059,6 +2101,16 @@ func (e *edgeState) erase(loc Location) {
fmt
.
Printf
(
"v%d no longer available in %s:%s
\n
"
,
vid
,
loc
.
Name
(),
c
)
fmt
.
Printf
(
"v%d no longer available in %s:%s
\n
"
,
vid
,
loc
.
Name
(),
c
)
}
}
a
[
i
],
a
=
a
[
len
(
a
)
-
1
],
a
[
:
len
(
a
)
-
1
]
a
[
i
],
a
=
a
[
len
(
a
)
-
1
],
a
[
:
len
(
a
)
-
1
]
if
e
.
s
.
f
.
Config
.
ctxt
.
Flag_locationlists
{
if
_
,
isReg
:=
loc
.
(
*
Register
);
isReg
&&
int
(
c
.
ID
)
<
len
(
e
.
s
.
valueNames
)
&&
len
(
e
.
s
.
valueNames
[
c
.
ID
])
!=
0
{
kill
:=
e
.
p
.
NewValue0
(
src
.
NoXPos
,
OpRegKill
,
types
.
TypeVoid
)
e
.
s
.
f
.
setHome
(
kill
,
loc
)
for
_
,
name
:=
range
e
.
s
.
valueNames
[
c
.
ID
]
{
e
.
s
.
f
.
NamedValues
[
name
]
=
append
(
e
.
s
.
f
.
NamedValues
[
name
],
kill
)
}
}
}
break
break
}
}
}
}
...
@@ -2118,8 +2170,8 @@ func (e *edgeState) findRegFor(typ *types.Type) Location {
...
@@ -2118,8 +2170,8 @@ func (e *edgeState) findRegFor(typ *types.Type) Location {
// Allocate a temp location to spill a register to.
// Allocate a temp location to spill a register to.
// The type of the slot is immaterial - it will not be live across
// The type of the slot is immaterial - it will not be live across
// any safepoint. Just use a type big enough to hold any register.
// any safepoint. Just use a type big enough to hold any register.
t
:=
LocalSlot
{
e
.
s
.
f
.
fe
.
Auto
(
c
.
Pos
,
types
.
Int64
),
types
.
Int64
,
0
}
t
:=
LocalSlot
{
N
:
e
.
s
.
f
.
fe
.
Auto
(
c
.
Pos
,
types
.
Int64
),
Type
:
types
.
Int64
}
// TODO: reuse these slots.
// TODO: reuse these slots.
They'll need to be erased first.
e
.
set
(
t
,
vid
,
x
,
false
,
c
.
Pos
)
e
.
set
(
t
,
vid
,
x
,
false
,
c
.
Pos
)
if
e
.
s
.
f
.
pass
.
debug
>
regDebug
{
if
e
.
s
.
f
.
pass
.
debug
>
regDebug
{
fmt
.
Printf
(
" SPILL %s->%s %s
\n
"
,
r
.
Name
(),
t
.
Name
(),
x
.
LongString
())
fmt
.
Printf
(
" SPILL %s->%s %s
\n
"
,
r
.
Name
(),
t
.
Name
(),
x
.
LongString
())
...
...
src/cmd/compile/internal/ssa/sizeof_test.go
View file @
385cd668
...
@@ -24,6 +24,7 @@ func TestSizeof(t *testing.T) {
...
@@ -24,6 +24,7 @@ func TestSizeof(t *testing.T) {
}{
}{
{
Value
{},
68
,
112
},
{
Value
{},
68
,
112
},
{
Block
{},
152
,
288
},
{
Block
{},
152
,
288
},
{
LocalSlot
{},
32
,
48
},
{
valState
{},
28
,
40
},
{
valState
{},
28
,
40
},
}
}
...
...
src/cmd/compile/internal/ssa/stackalloc.go
View file @
385cd668
...
@@ -151,7 +151,7 @@ func (s *stackAllocState) stackalloc() {
...
@@ -151,7 +151,7 @@ func (s *stackAllocState) stackalloc() {
if
v
.
Op
!=
OpArg
{
if
v
.
Op
!=
OpArg
{
continue
continue
}
}
loc
:=
LocalSlot
{
v
.
Aux
.
(
GCNode
),
v
.
Type
,
v
.
AuxInt
}
loc
:=
LocalSlot
{
N
:
v
.
Aux
.
(
GCNode
),
Type
:
v
.
Type
,
Off
:
v
.
AuxInt
}
if
f
.
pass
.
debug
>
stackDebug
{
if
f
.
pass
.
debug
>
stackDebug
{
fmt
.
Printf
(
"stackalloc %s to %s
\n
"
,
v
,
loc
.
Name
())
fmt
.
Printf
(
"stackalloc %s to %s
\n
"
,
v
,
loc
.
Name
())
}
}
...
...
src/cmd/compile/internal/ssa/value.go
View file @
385cd668
...
@@ -10,6 +10,7 @@ import (
...
@@ -10,6 +10,7 @@ import (
"cmd/internal/src"
"cmd/internal/src"
"fmt"
"fmt"
"math"
"math"
"strings"
)
)
// A Value represents a value in the SSA representation of the program.
// A Value represents a value in the SSA representation of the program.
...
@@ -98,7 +99,7 @@ func (v *Value) AuxValAndOff() ValAndOff {
...
@@ -98,7 +99,7 @@ func (v *Value) AuxValAndOff() ValAndOff {
return
ValAndOff
(
v
.
AuxInt
)
return
ValAndOff
(
v
.
AuxInt
)
}
}
// long form print. v# = opcode <type> [aux] args [: reg]
// long form print. v# = opcode <type> [aux] args [: reg]
(names)
func
(
v
*
Value
)
LongString
()
string
{
func
(
v
*
Value
)
LongString
()
string
{
s
:=
fmt
.
Sprintf
(
"v%d = %s"
,
v
.
ID
,
v
.
Op
)
s
:=
fmt
.
Sprintf
(
"v%d = %s"
,
v
.
ID
,
v
.
Op
)
s
+=
" <"
+
v
.
Type
.
String
()
+
">"
s
+=
" <"
+
v
.
Type
.
String
()
+
">"
...
@@ -110,6 +111,18 @@ func (v *Value) LongString() string {
...
@@ -110,6 +111,18 @@ func (v *Value) LongString() string {
if
int
(
v
.
ID
)
<
len
(
r
)
&&
r
[
v
.
ID
]
!=
nil
{
if
int
(
v
.
ID
)
<
len
(
r
)
&&
r
[
v
.
ID
]
!=
nil
{
s
+=
" : "
+
r
[
v
.
ID
]
.
Name
()
s
+=
" : "
+
r
[
v
.
ID
]
.
Name
()
}
}
var
names
[]
string
for
name
,
values
:=
range
v
.
Block
.
Func
.
NamedValues
{
for
_
,
value
:=
range
values
{
if
value
==
v
{
names
=
append
(
names
,
name
.
Name
())
break
// drop duplicates.
}
}
}
if
len
(
names
)
!=
0
{
s
+=
" ("
+
strings
.
Join
(
names
,
", "
)
+
")"
}
return
s
return
s
}
}
...
...
src/cmd/internal/dwarf/dwarf.go
View file @
385cd668
...
@@ -15,6 +15,9 @@ import (
...
@@ -15,6 +15,9 @@ import (
// 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 location lists.
const
LocPrefix
=
"go.loc."
// RangePrefix is the prefix for all the symbols containing DWARF range lists.
// RangePrefix is the prefix for all the symbols containing DWARF range lists.
const
RangePrefix
=
"go.range."
const
RangePrefix
=
"go.range."
...
@@ -23,13 +26,31 @@ type Sym interface {
...
@@ -23,13 +26,31 @@ type Sym interface {
Len
()
int64
Len
()
int64
}
}
// A Location represents a variable's location at a particular PC range.
// It becomes a location list entry in the DWARF.
type
Location
struct
{
StartPC
,
EndPC
int64
Pieces
[]
Piece
}
// A Piece represents the location of a particular part of a variable.
// It becomes part of a location list entry (a DW_OP_piece) in the DWARF.
type
Piece
struct
{
Length
int64
StackOffset
int32
RegNum
int16
Missing
bool
OnStack
bool
// if true, RegNum is unset.
}
// A Var represents a local variable or a function parameter.
// A Var represents a local variable or a function parameter.
type
Var
struct
{
type
Var
struct
{
Name
string
Name
string
Abbrev
int
// Either DW_ABRV_AUTO or DW_ABRV_PARAM
Abbrev
int
// Either DW_ABRV_AUTO or DW_ABRV_PARAM
Offset
int32
StackOffset
int32
Scope
int32
LocationList
[]
Location
Type
Sym
Scope
int32
Type
Sym
}
}
// A Scope represents a lexical scope. All variables declared within a
// A Scope represents a lexical scope. All variables declared within a
...
@@ -205,7 +226,7 @@ const (
...
@@ -205,7 +226,7 @@ const (
)
)
// Index into the abbrevs table below.
// Index into the abbrevs table below.
// Keep in sync with ispubname() and ispubtype()
below
.
// Keep in sync with ispubname() and ispubtype()
in ld/dwarf.go
.
// ispubtype considers >= NULLTYPE public
// ispubtype considers >= NULLTYPE public
const
(
const
(
DW_ABRV_NULL
=
iota
DW_ABRV_NULL
=
iota
...
@@ -213,7 +234,9 @@ const (
...
@@ -213,7 +234,9 @@ const (
DW_ABRV_FUNCTION
DW_ABRV_FUNCTION
DW_ABRV_VARIABLE
DW_ABRV_VARIABLE
DW_ABRV_AUTO
DW_ABRV_AUTO
DW_ABRV_AUTO_LOCLIST
DW_ABRV_PARAM
DW_ABRV_PARAM
DW_ABRV_PARAM_LOCLIST
DW_ABRV_LEXICAL_BLOCK_RANGES
DW_ABRV_LEXICAL_BLOCK_RANGES
DW_ABRV_LEXICAL_BLOCK_SIMPLE
DW_ABRV_LEXICAL_BLOCK_SIMPLE
DW_ABRV_STRUCTFIELD
DW_ABRV_STRUCTFIELD
...
@@ -297,6 +320,17 @@ var abbrevs = [DW_NABRV]dwAbbrev{
...
@@ -297,6 +320,17 @@ var abbrevs = [DW_NABRV]dwAbbrev{
},
},
},
},
/* AUTO_LOCLIST */
{
DW_TAG_variable
,
DW_CHILDREN_no
,
[]
dwAttrForm
{
{
DW_AT_name
,
DW_FORM_string
},
{
DW_AT_location
,
DW_FORM_sec_offset
},
{
DW_AT_type
,
DW_FORM_ref_addr
},
},
},
/* PARAM */
/* PARAM */
{
{
DW_TAG_formal_parameter
,
DW_TAG_formal_parameter
,
...
@@ -307,6 +341,18 @@ var abbrevs = [DW_NABRV]dwAbbrev{
...
@@ -307,6 +341,18 @@ var abbrevs = [DW_NABRV]dwAbbrev{
{
DW_AT_type
,
DW_FORM_ref_addr
},
{
DW_AT_type
,
DW_FORM_ref_addr
},
},
},
},
},
/* PARAM_LOCLIST */
{
DW_TAG_formal_parameter
,
DW_CHILDREN_no
,
[]
dwAttrForm
{
{
DW_AT_name
,
DW_FORM_string
},
{
DW_AT_location
,
DW_FORM_sec_offset
},
{
DW_AT_type
,
DW_FORM_ref_addr
},
},
},
/* LEXICAL_BLOCK_RANGES */
/* LEXICAL_BLOCK_RANGES */
{
{
DW_TAG_lexical_block
,
DW_TAG_lexical_block
,
...
@@ -684,31 +730,30 @@ func HasChildren(die *DWDie) bool {
...
@@ -684,31 +730,30 @@ 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
,
info
,
loc
,
ranges
Sym
,
name
string
,
external
bool
,
startPC
Sym
,
size
int64
,
scopes
[]
Scope
)
error
{
Uleb128put
(
ctxt
,
s
,
DW_ABRV_FUNCTION
)
Uleb128put
(
ctxt
,
info
,
DW_ABRV_FUNCTION
)
putattr
(
ctxt
,
s
,
DW_ABRV_FUNCTION
,
DW_FORM_string
,
DW_CLS_STRING
,
int64
(
len
(
name
)),
name
)
putattr
(
ctxt
,
info
,
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
,
info
,
DW_ABRV_FUNCTION
,
DW_FORM_addr
,
DW_CLS_ADDRESS
,
0
,
startPC
)
putattr
(
ctxt
,
s
,
DW_ABRV_FUNCTION
,
DW_FORM_addr
,
DW_CLS_ADDRESS
,
size
,
startPC
)
putattr
(
ctxt
,
info
,
DW_ABRV_FUNCTION
,
DW_FORM_addr
,
DW_CLS_ADDRESS
,
size
,
startPC
)
putattr
(
ctxt
,
s
,
DW_ABRV_FUNCTION
,
DW_FORM_block1
,
DW_CLS_BLOCK
,
1
,
[]
byte
{
DW_OP_call_frame_cfa
})
putattr
(
ctxt
,
info
,
DW_ABRV_FUNCTION
,
DW_FORM_block1
,
DW_CLS_BLOCK
,
1
,
[]
byte
{
DW_OP_call_frame_cfa
})
var
ev
int64
var
ev
int64
if
external
{
if
external
{
ev
=
1
ev
=
1
}
}
putattr
(
ctxt
,
s
,
DW_ABRV_FUNCTION
,
DW_FORM_flag
,
DW_CLS_FLAG
,
ev
,
0
)
putattr
(
ctxt
,
info
,
DW_ABRV_FUNCTION
,
DW_FORM_flag
,
DW_CLS_FLAG
,
ev
,
0
)
if
len
(
scopes
)
>
0
{
if
len
(
scopes
)
>
0
{
var
encbuf
[
20
]
byte
var
encbuf
[
20
]
byte
if
putscope
(
ctxt
,
s
,
ranges
,
startPC
,
0
,
scopes
,
encbuf
[
:
0
])
<
int32
(
len
(
scopes
))
{
if
putscope
(
ctxt
,
info
,
loc
,
ranges
,
startPC
,
0
,
scopes
,
encbuf
[
:
0
])
<
int32
(
len
(
scopes
))
{
return
errors
.
New
(
"multiple toplevel scopes"
)
return
errors
.
New
(
"multiple toplevel scopes"
)
}
}
}
}
Uleb128put
(
ctxt
,
info
,
0
)
Uleb128put
(
ctxt
,
s
,
0
)
return
nil
return
nil
}
}
func
putscope
(
ctxt
Context
,
s
,
ranges
Sym
,
startPC
Sym
,
curscope
int32
,
scopes
[]
Scope
,
encbuf
[]
byte
)
int32
{
func
putscope
(
ctxt
Context
,
info
,
loc
,
ranges
,
startPC
Sym
,
curscope
int32
,
scopes
[]
Scope
,
encbuf
[]
byte
)
int32
{
for
_
,
v
:=
range
scopes
[
curscope
]
.
Vars
{
for
_
,
v
:=
range
scopes
[
curscope
]
.
Vars
{
putvar
(
ctxt
,
s
,
v
,
encbuf
)
putvar
(
ctxt
,
info
,
loc
,
v
,
startPC
,
encbuf
)
}
}
this
:=
curscope
this
:=
curscope
curscope
++
curscope
++
...
@@ -719,12 +764,12 @@ func putscope(ctxt Context, s, ranges Sym, startPC Sym, curscope int32, scopes [
...
@@ -719,12 +764,12 @@ func putscope(ctxt Context, s, ranges Sym, startPC Sym, curscope int32, scopes [
}
}
if
len
(
scope
.
Ranges
)
==
1
{
if
len
(
scope
.
Ranges
)
==
1
{
Uleb128put
(
ctxt
,
s
,
DW_ABRV_LEXICAL_BLOCK_SIMPLE
)
Uleb128put
(
ctxt
,
info
,
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
,
info
,
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
)
putattr
(
ctxt
,
info
,
DW_ABRV_LEXICAL_BLOCK_SIMPLE
,
DW_FORM_addr
,
DW_CLS_ADDRESS
,
scope
.
Ranges
[
0
]
.
End
,
startPC
)
}
else
{
}
else
{
Uleb128put
(
ctxt
,
s
,
DW_ABRV_LEXICAL_BLOCK_RANGES
)
Uleb128put
(
ctxt
,
info
,
DW_ABRV_LEXICAL_BLOCK_RANGES
)
putattr
(
ctxt
,
s
,
DW_ABRV_LEXICAL_BLOCK_RANGES
,
DW_FORM_sec_offset
,
DW_CLS_PTR
,
ranges
.
Len
(),
ranges
)
putattr
(
ctxt
,
info
,
DW_ABRV_LEXICAL_BLOCK_RANGES
,
DW_FORM_sec_offset
,
DW_CLS_PTR
,
ranges
.
Len
(),
ranges
)
ctxt
.
AddAddress
(
ranges
,
nil
,
-
1
)
ctxt
.
AddAddress
(
ranges
,
nil
,
-
1
)
ctxt
.
AddAddress
(
ranges
,
startPC
,
0
)
ctxt
.
AddAddress
(
ranges
,
startPC
,
0
)
...
@@ -736,32 +781,72 @@ func putscope(ctxt Context, s, ranges Sym, startPC Sym, curscope int32, scopes [
...
@@ -736,32 +781,72 @@ func putscope(ctxt Context, s, ranges Sym, startPC Sym, curscope int32, scopes [
ctxt
.
AddAddress
(
ranges
,
nil
,
0
)
ctxt
.
AddAddress
(
ranges
,
nil
,
0
)
}
}
curscope
=
putscope
(
ctxt
,
s
,
ranges
,
startPC
,
curscope
,
scopes
,
encbuf
)
curscope
=
putscope
(
ctxt
,
info
,
loc
,
ranges
,
startPC
,
curscope
,
scopes
,
encbuf
)
Uleb128put
(
ctxt
,
s
,
0
)
Uleb128put
(
ctxt
,
info
,
0
)
}
}
return
curscope
return
curscope
}
}
func
putvar
(
ctxt
Context
,
s
Sym
,
v
*
Var
,
encbuf
[]
byte
)
{
func
putvar
(
ctxt
Context
,
info
,
loc
Sym
,
v
*
Var
,
startPC
Sym
,
encbuf
[]
byte
)
{
n
:=
v
.
Name
n
:=
v
.
Name
Uleb128put
(
ctxt
,
s
,
int64
(
v
.
Abbrev
))
Uleb128put
(
ctxt
,
info
,
int64
(
v
.
Abbrev
))
putattr
(
ctxt
,
s
,
v
.
Abbrev
,
DW_FORM_string
,
DW_CLS_STRING
,
int64
(
len
(
n
)),
n
)
putattr
(
ctxt
,
info
,
v
.
Abbrev
,
DW_FORM_string
,
DW_CLS_STRING
,
int64
(
len
(
n
)),
n
)
loc
:=
append
(
encbuf
[
:
0
],
DW_OP_call_frame_cfa
)
if
v
.
Abbrev
==
DW_ABRV_AUTO_LOCLIST
||
v
.
Abbrev
==
DW_ABRV_PARAM_LOCLIST
{
if
v
.
Offset
!=
0
{
putattr
(
ctxt
,
info
,
v
.
Abbrev
,
DW_FORM_sec_offset
,
DW_CLS_PTR
,
int64
(
loc
.
Len
()),
loc
)
loc
=
append
(
loc
,
DW_OP_consts
)
addLocList
(
ctxt
,
loc
,
startPC
,
v
,
encbuf
)
loc
=
AppendSleb128
(
loc
,
int64
(
v
.
Offset
))
}
else
{
loc
=
append
(
loc
,
DW_OP_plus
)
loc
:=
append
(
encbuf
[
:
0
],
DW_OP_call_frame_cfa
)
if
v
.
StackOffset
!=
0
{
loc
=
append
(
loc
,
DW_OP_consts
)
loc
=
AppendSleb128
(
loc
,
int64
(
v
.
StackOffset
))
loc
=
append
(
loc
,
DW_OP_plus
)
}
putattr
(
ctxt
,
info
,
v
.
Abbrev
,
DW_FORM_block1
,
DW_CLS_BLOCK
,
int64
(
len
(
loc
)),
loc
)
}
putattr
(
ctxt
,
info
,
v
.
Abbrev
,
DW_FORM_ref_addr
,
DW_CLS_REFERENCE
,
0
,
v
.
Type
)
}
func
addLocList
(
ctxt
Context
,
listSym
,
startPC
Sym
,
v
*
Var
,
encbuf
[]
byte
)
{
// Base address entry: max ptr followed by the base address.
ctxt
.
AddInt
(
listSym
,
ctxt
.
PtrSize
(),
^
0
)
ctxt
.
AddAddress
(
listSym
,
startPC
,
0
)
for
_
,
entry
:=
range
v
.
LocationList
{
ctxt
.
AddInt
(
listSym
,
ctxt
.
PtrSize
(),
entry
.
StartPC
)
ctxt
.
AddInt
(
listSym
,
ctxt
.
PtrSize
(),
entry
.
EndPC
)
locBuf
:=
encbuf
[
:
0
]
for
_
,
piece
:=
range
entry
.
Pieces
{
if
!
piece
.
Missing
{
if
piece
.
OnStack
{
locBuf
=
append
(
locBuf
,
DW_OP_fbreg
)
locBuf
=
AppendSleb128
(
locBuf
,
int64
(
piece
.
StackOffset
))
}
else
{
if
piece
.
RegNum
<
32
{
locBuf
=
append
(
locBuf
,
DW_OP_reg0
+
byte
(
piece
.
RegNum
))
}
else
{
locBuf
=
append
(
locBuf
,
DW_OP_regx
)
locBuf
=
AppendUleb128
(
locBuf
,
uint64
(
piece
.
RegNum
))
}
}
}
if
len
(
entry
.
Pieces
)
>
1
{
locBuf
=
append
(
locBuf
,
DW_OP_piece
)
locBuf
=
AppendUleb128
(
locBuf
,
uint64
(
piece
.
Length
))
}
}
ctxt
.
AddInt
(
listSym
,
2
,
int64
(
len
(
locBuf
)))
ctxt
.
AddBytes
(
listSym
,
locBuf
)
}
}
putattr
(
ctxt
,
s
,
v
.
Abbrev
,
DW_FORM_block1
,
DW_CLS_BLOCK
,
int64
(
len
(
loc
)),
loc
)
// End list
putattr
(
ctxt
,
s
,
v
.
Abbrev
,
DW_FORM_ref_addr
,
DW_CLS_REFERENCE
,
0
,
v
.
Type
)
ctxt
.
AddInt
(
listSym
,
ctxt
.
PtrSize
(),
0
)
ctxt
.
AddInt
(
listSym
,
ctxt
.
PtrSize
(),
0
)
}
}
// VarsByOffset attaches the methods of sort.Interface to []*Var,
// VarsByOffset attaches the methods of sort.Interface to []*Var,
// sorting in increasing Offset.
// sorting in increasing
Stack
Offset.
type
VarsByOffset
[]
*
Var
type
VarsByOffset
[]
*
Var
func
(
s
VarsByOffset
)
Len
()
int
{
return
len
(
s
)
}
func
(
s
VarsByOffset
)
Len
()
int
{
return
len
(
s
)
}
func
(
s
VarsByOffset
)
Less
(
i
,
j
int
)
bool
{
return
s
[
i
]
.
Offset
<
s
[
j
]
.
Offset
}
func
(
s
VarsByOffset
)
Less
(
i
,
j
int
)
bool
{
return
s
[
i
]
.
StackOffset
<
s
[
j
]
.
Stack
Offset
}
func
(
s
VarsByOffset
)
Swap
(
i
,
j
int
)
{
s
[
i
],
s
[
j
]
=
s
[
j
],
s
[
i
]
}
func
(
s
VarsByOffset
)
Swap
(
i
,
j
int
)
{
s
[
i
],
s
[
j
]
=
s
[
j
],
s
[
i
]
}
src/cmd/internal/obj/link.go
View file @
385cd668
...
@@ -330,7 +330,8 @@ type FuncInfo struct {
...
@@ -330,7 +330,8 @@ type FuncInfo struct {
Autom
[]
*
Auto
Autom
[]
*
Auto
Pcln
Pcln
Pcln
Pcln
dwarfSym
*
LSym
dwarfInfoSym
*
LSym
dwarfLocSym
*
LSym
dwarfRangesSym
*
LSym
dwarfRangesSym
*
LSym
GCArgs
LSym
GCArgs
LSym
...
@@ -476,25 +477,26 @@ type Pcdata struct {
...
@@ -476,25 +477,26 @@ type Pcdata struct {
// Link holds the context for writing object code from a compiler
// Link holds the context for writing object code from a compiler
// to be linker input or for reading that input into the linker.
// to be linker input or for reading that input into the linker.
type
Link
struct
{
type
Link
struct
{
Headtype
objabi
.
HeadType
Headtype
objabi
.
HeadType
Arch
*
LinkArch
Arch
*
LinkArch
Debugasm
bool
Debugasm
bool
Debugvlog
bool
Debugvlog
bool
Debugpcln
string
Debugpcln
string
Flag_shared
bool
Flag_shared
bool
Flag_dynlink
bool
Flag_dynlink
bool
Flag_optimize
bool
Flag_optimize
bool
Bso
*
bufio
.
Writer
Flag_locationlists
bool
Pathname
string
Bso
*
bufio
.
Writer
hashmu
sync
.
Mutex
// protects hash
Pathname
string
hash
map
[
string
]
*
LSym
// name -> sym mapping
hashmu
sync
.
Mutex
// protects hash
statichash
map
[
string
]
*
LSym
// name -> sym mapping for static syms
hash
map
[
string
]
*
LSym
// name -> sym mapping
PosTable
src
.
PosTable
statichash
map
[
string
]
*
LSym
// name -> sym mapping for static syms
InlTree
InlTree
// global inlining tree used by gc/inl.go
PosTable
src
.
PosTable
Imports
[]
string
InlTree
InlTree
// global inlining tree used by gc/inl.go
DiagFunc
func
(
string
,
...
interface
{})
Imports
[]
string
DebugInfo
func
(
fn
*
LSym
,
curfn
interface
{})
[]
dwarf
.
Scope
// if non-nil, curfn is a *gc.Node
DiagFunc
func
(
string
,
...
interface
{})
Errors
int
DebugInfo
func
(
fn
*
LSym
,
curfn
interface
{})
[]
dwarf
.
Scope
// if non-nil, curfn is a *gc.Node
Errors
int
Framepointer_enabled
bool
Framepointer_enabled
bool
...
@@ -533,9 +535,10 @@ func (ctxt *Link) FixedFrameSize() int64 {
...
@@ -533,9 +535,10 @@ func (ctxt *Link) FixedFrameSize() int64 {
// LinkArch is the definition of a single architecture.
// LinkArch is the definition of a single architecture.
type
LinkArch
struct
{
type
LinkArch
struct
{
*
sys
.
Arch
*
sys
.
Arch
Init
func
(
*
Link
)
Init
func
(
*
Link
)
Preprocess
func
(
*
Link
,
*
LSym
,
ProgAlloc
)
Preprocess
func
(
*
Link
,
*
LSym
,
ProgAlloc
)
Assemble
func
(
*
Link
,
*
LSym
,
ProgAlloc
)
Assemble
func
(
*
Link
,
*
LSym
,
ProgAlloc
)
Progedit
func
(
*
Link
,
*
Prog
,
ProgAlloc
)
Progedit
func
(
*
Link
,
*
Prog
,
ProgAlloc
)
UnaryDst
map
[
As
]
bool
// Instruction takes one operand, a destination.
UnaryDst
map
[
As
]
bool
// Instruction takes one operand, a destination.
DWARFRegisters
map
[
int16
]
int16
}
}
src/cmd/internal/obj/objfile.go
View file @
385cd668
...
@@ -465,15 +465,18 @@ func (c dwCtxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64
...
@@ -465,15 +465,18 @@ func (c dwCtxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64
}
}
// dwarfSym returns the DWARF symbols for TEXT symbol.
// dwarfSym returns the DWARF symbols for TEXT symbol.
func
(
ctxt
*
Link
)
dwarfSym
(
s
*
LSym
)
(
dwarfInfoSym
,
dwarfRangesSym
*
LSym
)
{
func
(
ctxt
*
Link
)
dwarfSym
(
s
*
LSym
)
(
dwarfInfoSym
,
dwarf
LocSym
,
dwarf
RangesSym
*
LSym
)
{
if
s
.
Type
!=
objabi
.
STEXT
{
if
s
.
Type
!=
objabi
.
STEXT
{
ctxt
.
Diag
(
"dwarfSym of non-TEXT %v"
,
s
)
ctxt
.
Diag
(
"dwarfSym of non-TEXT %v"
,
s
)
}
}
if
s
.
Func
.
dwarfSym
==
nil
{
if
s
.
Func
.
dwarfInfoSym
==
nil
{
s
.
Func
.
dwarfSym
=
ctxt
.
LookupDerived
(
s
,
dwarf
.
InfoPrefix
+
s
.
Name
)
s
.
Func
.
dwarfInfoSym
=
ctxt
.
LookupDerived
(
s
,
dwarf
.
InfoPrefix
+
s
.
Name
)
if
ctxt
.
Flag_locationlists
{
s
.
Func
.
dwarfLocSym
=
ctxt
.
LookupDerived
(
s
,
dwarf
.
LocPrefix
+
s
.
Name
)
}
s
.
Func
.
dwarfRangesSym
=
ctxt
.
LookupDerived
(
s
,
dwarf
.
RangePrefix
+
s
.
Name
)
s
.
Func
.
dwarfRangesSym
=
ctxt
.
LookupDerived
(
s
,
dwarf
.
RangePrefix
+
s
.
Name
)
}
}
return
s
.
Func
.
dwarfSym
,
s
.
Func
.
dwarfRangesSym
return
s
.
Func
.
dwarf
InfoSym
,
s
.
Func
.
dwarfLoc
Sym
,
s
.
Func
.
dwarfRangesSym
}
}
func
(
s
*
LSym
)
Len
()
int64
{
func
(
s
*
LSym
)
Len
()
int64
{
...
@@ -483,15 +486,15 @@ func (s *LSym) Len() int64 {
...
@@ -483,15 +486,15 @@ func (s *LSym) Len() int64 {
// populateDWARF fills in the DWARF Debugging Information Entries for TEXT symbol s.
// populateDWARF fills in the DWARF Debugging Information Entries for TEXT symbol s.
// The DWARFs symbol must already have been initialized in InitTextSym.
// The DWARFs symbol must already have been initialized in InitTextSym.
func
(
ctxt
*
Link
)
populateDWARF
(
curfn
interface
{},
s
*
LSym
)
{
func
(
ctxt
*
Link
)
populateDWARF
(
curfn
interface
{},
s
*
LSym
)
{
dsym
,
drsym
:=
ctxt
.
dwarfSym
(
s
)
info
,
loc
,
ranges
:=
ctxt
.
dwarfSym
(
s
)
if
dsym
.
Size
!=
0
{
if
info
.
Size
!=
0
{
ctxt
.
Diag
(
"makeFuncDebugEntry double process %v"
,
s
)
ctxt
.
Diag
(
"makeFuncDebugEntry double process %v"
,
s
)
}
}
var
scopes
[]
dwarf
.
Scope
var
scopes
[]
dwarf
.
Scope
if
ctxt
.
DebugInfo
!=
nil
{
if
ctxt
.
DebugInfo
!=
nil
{
scopes
=
ctxt
.
DebugInfo
(
s
,
curfn
)
scopes
=
ctxt
.
DebugInfo
(
s
,
curfn
)
}
}
err
:=
dwarf
.
PutFunc
(
dwCtxt
{
ctxt
},
dsym
,
drsym
,
s
.
Name
,
!
s
.
Static
(),
s
,
s
.
Size
,
scopes
)
err
:=
dwarf
.
PutFunc
(
dwCtxt
{
ctxt
},
info
,
loc
,
ranges
,
s
.
Name
,
!
s
.
Static
(),
s
,
s
.
Size
,
scopes
)
if
err
!=
nil
{
if
err
!=
nil
{
ctxt
.
Diag
(
"emitting DWARF for %s failed: %v"
,
s
.
Name
,
err
)
ctxt
.
Diag
(
"emitting DWARF for %s failed: %v"
,
s
.
Name
,
err
)
}
}
...
...
src/cmd/internal/obj/plist.go
View file @
385cd668
...
@@ -136,13 +136,17 @@ func (ctxt *Link) InitTextSym(s *LSym, flag int) {
...
@@ -136,13 +136,17 @@ func (ctxt *Link) InitTextSym(s *LSym, flag int) {
ctxt
.
Text
=
append
(
ctxt
.
Text
,
s
)
ctxt
.
Text
=
append
(
ctxt
.
Text
,
s
)
// Set up DWARF entries for s.
// Set up DWARF entries for s.
dsym
,
drsym
:=
ctxt
.
dwarfSym
(
s
)
info
,
loc
,
ranges
:=
ctxt
.
dwarfSym
(
s
)
dsym
.
Type
=
objabi
.
SDWARFINFO
info
.
Type
=
objabi
.
SDWARFINFO
dsym
.
Set
(
AttrDuplicateOK
,
s
.
DuplicateOK
())
info
.
Set
(
AttrDuplicateOK
,
s
.
DuplicateOK
())
drsym
.
Type
=
objabi
.
SDWARFRANGE
if
loc
!=
nil
{
drsym
.
Set
(
AttrDuplicateOK
,
s
.
DuplicateOK
())
loc
.
Type
=
objabi
.
SDWARFLOC
ctxt
.
Data
=
append
(
ctxt
.
Data
,
dsym
)
loc
.
Set
(
AttrDuplicateOK
,
s
.
DuplicateOK
())
ctxt
.
Data
=
append
(
ctxt
.
Data
,
drsym
)
ctxt
.
Data
=
append
(
ctxt
.
Data
,
loc
)
}
ranges
.
Type
=
objabi
.
SDWARFRANGE
ranges
.
Set
(
AttrDuplicateOK
,
s
.
DuplicateOK
())
ctxt
.
Data
=
append
(
ctxt
.
Data
,
info
,
ranges
)
// Set up the function's gcargs and gclocals.
// Set up the function's gcargs and gclocals.
// They will be filled in later if needed.
// They will be filled in later if needed.
...
...
src/cmd/internal/obj/x86/a.out.go
View file @
385cd668
...
@@ -1006,3 +1006,120 @@ const (
...
@@ -1006,3 +1006,120 @@ const (
T_64
=
1
<<
6
T_64
=
1
<<
6
T_GOTYPE
=
1
<<
7
T_GOTYPE
=
1
<<
7
)
)
// https://www.uclibc.org/docs/psABI-x86_64.pdf, figure 3.36
var
AMD64DWARFRegisters
=
map
[
int16
]
int16
{
REG_AX
:
0
,
REG_DX
:
1
,
REG_CX
:
2
,
REG_BX
:
3
,
REG_SI
:
4
,
REG_DI
:
5
,
REG_BP
:
6
,
REG_SP
:
7
,
REG_R8
:
8
,
REG_R9
:
9
,
REG_R10
:
10
,
REG_R11
:
11
,
REG_R12
:
12
,
REG_R13
:
13
,
REG_R14
:
14
,
REG_R15
:
15
,
// 16 is "Return Address RA", whatever that is.
// XMM registers. %xmmN => XN.
REG_X0
:
17
,
REG_X1
:
18
,
REG_X2
:
19
,
REG_X3
:
20
,
REG_X4
:
21
,
REG_X5
:
22
,
REG_X6
:
23
,
REG_X7
:
24
,
REG_X8
:
25
,
REG_X9
:
26
,
REG_X10
:
27
,
REG_X11
:
28
,
REG_X12
:
29
,
REG_X13
:
30
,
REG_X14
:
31
,
REG_X15
:
32
,
// ST registers. %stN => FN.
REG_F0
:
33
,
REG_F1
:
34
,
REG_F2
:
35
,
REG_F3
:
36
,
REG_F4
:
37
,
REG_F5
:
38
,
REG_F6
:
39
,
REG_F7
:
40
,
// MMX registers. %mmN => MN.
REG_M0
:
41
,
REG_M1
:
42
,
REG_M2
:
43
,
REG_M3
:
44
,
REG_M4
:
45
,
REG_M5
:
46
,
REG_M6
:
47
,
REG_M7
:
48
,
// 48 is flags, which doesn't have a name.
REG_ES
:
50
,
REG_CS
:
51
,
REG_SS
:
52
,
REG_DS
:
53
,
REG_FS
:
54
,
REG_GS
:
55
,
// 58 and 59 are {fs,gs}base, which don't have names.
REG_TR
:
62
,
REG_LDTR
:
63
,
// 64-66 are mxcsr, fcw, fsw, which don't have names.
}
// https://www.uclibc.org/docs/psABI-i386.pdf, table 2.14
var
X86DWARFRegisters
=
map
[
int16
]
int16
{
REG_AX
:
0
,
REG_CX
:
1
,
REG_DX
:
2
,
REG_BX
:
3
,
REG_SP
:
4
,
REG_BP
:
5
,
REG_SI
:
6
,
REG_DI
:
7
,
// 8 is "Return Address RA", whatever that is.
// 9 is flags, which doesn't have a name.
// ST registers. %stN => FN.
REG_F0
:
11
,
REG_F1
:
12
,
REG_F2
:
13
,
REG_F3
:
14
,
REG_F4
:
15
,
REG_F5
:
16
,
REG_F6
:
17
,
REG_F7
:
18
,
// XMM registers. %xmmN => XN.
REG_X0
:
21
,
REG_X1
:
22
,
REG_X2
:
23
,
REG_X3
:
24
,
REG_X4
:
25
,
REG_X5
:
26
,
REG_X6
:
27
,
REG_X7
:
28
,
// MMX registers. %mmN => MN.
REG_M0
:
29
,
REG_M1
:
30
,
REG_M2
:
31
,
REG_M3
:
32
,
REG_M4
:
33
,
REG_M5
:
34
,
REG_M6
:
35
,
REG_M7
:
36
,
// 39 is mxcsr, which doesn't have a name.
REG_ES
:
40
,
REG_CS
:
41
,
REG_SS
:
42
,
REG_DS
:
43
,
REG_FS
:
44
,
REG_GS
:
45
,
REG_TR
:
48
,
REG_LDTR
:
49
,
}
src/cmd/internal/obj/x86/obj6.go
View file @
385cd668
...
@@ -1231,28 +1231,31 @@ var unaryDst = map[obj.As]bool{
...
@@ -1231,28 +1231,31 @@ var unaryDst = map[obj.As]bool{
}
}
var
Linkamd64
=
obj
.
LinkArch
{
var
Linkamd64
=
obj
.
LinkArch
{
Arch
:
sys
.
ArchAMD64
,
Arch
:
sys
.
ArchAMD64
,
Init
:
instinit
,
Init
:
instinit
,
Preprocess
:
preprocess
,
Preprocess
:
preprocess
,
Assemble
:
span6
,
Assemble
:
span6
,
Progedit
:
progedit
,
Progedit
:
progedit
,
UnaryDst
:
unaryDst
,
UnaryDst
:
unaryDst
,
DWARFRegisters
:
AMD64DWARFRegisters
,
}
}
var
Linkamd64p32
=
obj
.
LinkArch
{
var
Linkamd64p32
=
obj
.
LinkArch
{
Arch
:
sys
.
ArchAMD64P32
,
Arch
:
sys
.
ArchAMD64P32
,
Init
:
instinit
,
Init
:
instinit
,
Preprocess
:
preprocess
,
Preprocess
:
preprocess
,
Assemble
:
span6
,
Assemble
:
span6
,
Progedit
:
progedit
,
Progedit
:
progedit
,
UnaryDst
:
unaryDst
,
UnaryDst
:
unaryDst
,
DWARFRegisters
:
AMD64DWARFRegisters
,
}
}
var
Link386
=
obj
.
LinkArch
{
var
Link386
=
obj
.
LinkArch
{
Arch
:
sys
.
Arch386
,
Arch
:
sys
.
Arch386
,
Init
:
instinit
,
Init
:
instinit
,
Preprocess
:
preprocess
,
Preprocess
:
preprocess
,
Assemble
:
span6
,
Assemble
:
span6
,
Progedit
:
progedit
,
Progedit
:
progedit
,
UnaryDst
:
unaryDst
,
UnaryDst
:
unaryDst
,
DWARFRegisters
:
AMD64DWARFRegisters
,
}
}
src/cmd/internal/objabi/symkind.go
View file @
385cd668
...
@@ -57,4 +57,5 @@ const (
...
@@ -57,4 +57,5 @@ const (
// Debugging data
// Debugging data
SDWARFINFO
SDWARFINFO
SDWARFRANGE
SDWARFRANGE
SDWARFLOC
)
)
src/cmd/internal/objabi/symkind_string.go
View file @
385cd668
...
@@ -4,9 +4,9 @@ package objabi
...
@@ -4,9 +4,9 @@ package objabi
import
"fmt"
import
"fmt"
const
_SymKind_name
=
"SxxxSTEXTSRODATASNOPTRDATASDATASBSSSNOPTRBSSSTLSBSSSDWARFINFOSDWARFRANGE"
const
_SymKind_name
=
"SxxxSTEXTSRODATASNOPTRDATASDATASBSSSNOPTRBSSSTLSBSSSDWARFINFOSDWARFRANGE
SDWARFLOC
"
var
_SymKind_index
=
[
...
]
uint8
{
0
,
4
,
9
,
16
,
26
,
31
,
35
,
44
,
51
,
61
,
72
}
var
_SymKind_index
=
[
...
]
uint8
{
0
,
4
,
9
,
16
,
26
,
31
,
35
,
44
,
51
,
61
,
72
,
81
}
func
(
i
SymKind
)
String
()
string
{
func
(
i
SymKind
)
String
()
string
{
if
i
>=
SymKind
(
len
(
_SymKind_index
)
-
1
)
{
if
i
>=
SymKind
(
len
(
_SymKind_index
)
-
1
)
{
...
...
src/cmd/link/internal/ld/data.go
View file @
385cd668
...
@@ -592,15 +592,7 @@ func relocsym(ctxt *Link, s *Symbol) {
...
@@ -592,15 +592,7 @@ func relocsym(ctxt *Link, s *Symbol) {
}
}
case
objabi
.
R_DWARFREF
:
case
objabi
.
R_DWARFREF
:
var
sectName
string
if
r
.
Sym
.
Sect
==
nil
{
var
vaddr
int64
switch
{
case
r
.
Sym
.
Sect
!=
nil
:
sectName
=
r
.
Sym
.
Sect
.
Name
vaddr
=
int64
(
r
.
Sym
.
Sect
.
Vaddr
)
case
r
.
Sym
.
Type
==
SDWARFRANGE
:
sectName
=
".debug_ranges"
default
:
Errorf
(
s
,
"missing DWARF section for relocation target %s"
,
r
.
Sym
.
Name
)
Errorf
(
s
,
"missing DWARF section for relocation target %s"
,
r
.
Sym
.
Name
)
}
}
...
@@ -615,8 +607,8 @@ func relocsym(ctxt *Link, s *Symbol) {
...
@@ -615,8 +607,8 @@ func relocsym(ctxt *Link, s *Symbol) {
r
.
Type
=
objabi
.
R_ADDR
r
.
Type
=
objabi
.
R_ADDR
}
}
r
.
Xsym
=
ctxt
.
Syms
.
ROLookup
(
sect
Name
,
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
...
@@ -625,7 +617,7 @@ func relocsym(ctxt *Link, s *Symbol) {
...
@@ -625,7 +617,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
objabi
.
R_WEAKADDROFF
:
case
objabi
.
R_WEAKADDROFF
:
if
!
r
.
Sym
.
Attr
.
Reachable
()
{
if
!
r
.
Sym
.
Attr
.
Reachable
()
{
...
@@ -1843,9 +1835,9 @@ func (ctxt *Link) dodata() {
...
@@ -1843,9 +1835,9 @@ func (ctxt *Link) dodata() {
dwarfgeneratedebugsyms
(
ctxt
)
dwarfgeneratedebugsyms
(
ctxt
)
var
s
*
Symbol
var
i
int
var
i
int
for
i
,
s
=
range
dwarfp
{
for
;
i
<
len
(
dwarfp
);
i
++
{
s
:=
dwarfp
[
i
]
if
s
.
Type
!=
SDWARFSECT
{
if
s
.
Type
!=
SDWARFSECT
{
break
break
}
}
...
@@ -1862,13 +1854,26 @@ func (ctxt *Link) dodata() {
...
@@ -1862,13 +1854,26 @@ func (ctxt *Link) dodata() {
}
}
checkdatsize
(
ctxt
,
datsize
,
SDWARFSECT
)
checkdatsize
(
ctxt
,
datsize
,
SDWARFSECT
)
if
i
<
len
(
dwarfp
)
{
for
i
<
len
(
dwarfp
)
{
sect
=
addsection
(
&
Segdwarf
,
".debug_info"
,
04
)
curType
:=
dwarfp
[
i
]
.
Type
var
sect
*
Section
switch
curType
{
case
SDWARFINFO
:
sect
=
addsection
(
&
Segdwarf
,
".debug_info"
,
04
)
case
SDWARFRANGE
:
sect
=
addsection
(
&
Segdwarf
,
".debug_ranges"
,
04
)
case
SDWARFLOC
:
sect
=
addsection
(
&
Segdwarf
,
".debug_loc"
,
04
)
default
:
Errorf
(
dwarfp
[
i
],
"unknown DWARF section %v"
,
curType
)
}
sect
.
Align
=
1
sect
.
Align
=
1
datsize
=
Rnd
(
datsize
,
int64
(
sect
.
Align
))
datsize
=
Rnd
(
datsize
,
int64
(
sect
.
Align
))
sect
.
Vaddr
=
uint64
(
datsize
)
sect
.
Vaddr
=
uint64
(
datsize
)
for
_
,
s
:=
range
dwarfp
[
i
:
]
{
for
;
i
<
len
(
dwarfp
);
i
++
{
if
s
.
Type
!=
SDWARFINFO
{
s
:=
dwarfp
[
i
]
if
s
.
Type
!=
curType
{
break
break
}
}
s
.
Sect
=
sect
s
.
Sect
=
sect
...
@@ -1878,7 +1883,7 @@ func (ctxt *Link) dodata() {
...
@@ -1878,7 +1883,7 @@ func (ctxt *Link) dodata() {
datsize
+=
s
.
Size
datsize
+=
s
.
Size
}
}
sect
.
Length
=
uint64
(
datsize
)
-
sect
.
Vaddr
sect
.
Length
=
uint64
(
datsize
)
-
sect
.
Vaddr
checkdatsize
(
ctxt
,
datsize
,
SDWARFINFO
)
checkdatsize
(
ctxt
,
datsize
,
curType
)
}
}
/* number the sections */
/* number the sections */
...
...
src/cmd/link/internal/ld/dwarf.go
View file @
385cd668
...
@@ -67,26 +67,15 @@ func (c dwctxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64
...
@@ -67,26 +67,15 @@ func (c dwctxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64
r
.
Add
=
ofs
r
.
Add
=
ofs
}
}
/*
* Offsets and sizes of the debug_* sections in the cout file.
*/
var
abbrevsym
*
Symbol
var
arangessec
*
Symbol
var
framesec
*
Symbol
var
infosec
*
Symbol
var
linesec
*
Symbol
var
rangesec
*
Symbol
var
gdbscript
string
var
gdbscript
string
var
dwarfp
[]
*
Symbol
var
dwarfp
[]
*
Symbol
func
writeabbrev
(
ctxt
*
Link
,
syms
[]
*
Symbol
)
[]
*
Symbol
{
func
writeabbrev
(
ctxt
*
Link
)
*
Symbol
{
s
:=
ctxt
.
Syms
.
Lookup
(
".debug_abbrev"
,
0
)
s
:=
ctxt
.
Syms
.
Lookup
(
".debug_abbrev"
,
0
)
s
.
Type
=
SDWARFSECT
s
.
Type
=
SDWARFSECT
abbrevsym
=
s
Addbytes
(
s
,
dwarf
.
GetAbbrev
())
Addbytes
(
s
,
dwarf
.
GetAbbrev
())
return
append
(
syms
,
s
)
return
s
}
}
/*
/*
...
@@ -993,13 +982,10 @@ func getCompilationDir() string {
...
@@ -993,13 +982,10 @@ func getCompilationDir() string {
func
writelines
(
ctxt
*
Link
,
syms
[]
*
Symbol
)
([]
*
Symbol
,
[]
*
Symbol
)
{
func
writelines
(
ctxt
*
Link
,
syms
[]
*
Symbol
)
([]
*
Symbol
,
[]
*
Symbol
)
{
var
dwarfctxt
dwarf
.
Context
=
dwctxt
{
ctxt
}
var
dwarfctxt
dwarf
.
Context
=
dwctxt
{
ctxt
}
if
linesec
==
nil
{
ls
:=
ctxt
.
Syms
.
Lookup
(
".debug_line"
,
0
)
linesec
=
ctxt
.
Syms
.
Lookup
(
".debug_line"
,
0
)
ls
.
Type
=
SDWARFSECT
}
ls
.
R
=
ls
.
R
[
:
0
]
linesec
.
Type
=
SDWARFSECT
linesec
.
R
=
linesec
.
R
[
:
0
]
ls
:=
linesec
syms
=
append
(
syms
,
ls
)
syms
=
append
(
syms
,
ls
)
var
funcs
[]
*
Symbol
var
funcs
[]
*
Symbol
...
@@ -1019,7 +1005,7 @@ func writelines(ctxt *Link, syms []*Symbol) ([]*Symbol, []*Symbol) {
...
@@ -1019,7 +1005,7 @@ func writelines(ctxt *Link, syms []*Symbol) ([]*Symbol, []*Symbol) {
dwinfo
=
newdie
(
ctxt
,
&
dwroot
,
dwarf
.
DW_ABRV_COMPUNIT
,
"go"
,
0
)
dwinfo
=
newdie
(
ctxt
,
&
dwroot
,
dwarf
.
DW_ABRV_COMPUNIT
,
"go"
,
0
)
newattr
(
dwinfo
,
dwarf
.
DW_AT_language
,
dwarf
.
DW_CLS_CONSTANT
,
int64
(
lang
),
0
)
newattr
(
dwinfo
,
dwarf
.
DW_AT_language
,
dwarf
.
DW_CLS_CONSTANT
,
int64
(
lang
),
0
)
newattr
(
dwinfo
,
dwarf
.
DW_AT_stmt_list
,
dwarf
.
DW_CLS_PTR
,
0
,
l
inesec
)
newattr
(
dwinfo
,
dwarf
.
DW_AT_stmt_list
,
dwarf
.
DW_CLS_PTR
,
0
,
l
s
)
newattr
(
dwinfo
,
dwarf
.
DW_AT_low_pc
,
dwarf
.
DW_CLS_ADDRESS
,
s
.
Value
,
s
)
newattr
(
dwinfo
,
dwarf
.
DW_AT_low_pc
,
dwarf
.
DW_CLS_ADDRESS
,
s
.
Value
,
s
)
// OS X linker requires compilation dir or absolute path in comp unit name to output debug info.
// OS X linker requires compilation dir or absolute path in comp unit name to output debug info.
compDir
:=
getCompilationDir
()
compDir
:=
getCompilationDir
()
...
@@ -1178,12 +1164,9 @@ func appendPCDeltaCFA(b []byte, deltapc, cfa int64) []byte {
...
@@ -1178,12 +1164,9 @@ func appendPCDeltaCFA(b []byte, deltapc, cfa int64) []byte {
func
writeframes
(
ctxt
*
Link
,
syms
[]
*
Symbol
)
[]
*
Symbol
{
func
writeframes
(
ctxt
*
Link
,
syms
[]
*
Symbol
)
[]
*
Symbol
{
var
dwarfctxt
dwarf
.
Context
=
dwctxt
{
ctxt
}
var
dwarfctxt
dwarf
.
Context
=
dwctxt
{
ctxt
}
if
framesec
==
nil
{
fs
:=
ctxt
.
Syms
.
Lookup
(
".debug_frame"
,
0
)
framesec
=
ctxt
.
Syms
.
Lookup
(
".debug_frame"
,
0
)
fs
.
Type
=
SDWARFSECT
}
fs
.
R
=
fs
.
R
[
:
0
]
framesec
.
Type
=
SDWARFSECT
framesec
.
R
=
framesec
.
R
[
:
0
]
fs
:=
framesec
syms
=
append
(
syms
,
fs
)
syms
=
append
(
syms
,
fs
)
// Emit the CIE, Section 6.4.1
// Emit the CIE, Section 6.4.1
...
@@ -1280,7 +1263,7 @@ func writeframes(ctxt *Link, syms []*Symbol) []*Symbol {
...
@@ -1280,7 +1263,7 @@ func writeframes(ctxt *Link, syms []*Symbol) []*Symbol {
// ptrsize: address range
// ptrsize: address range
Adduint32
(
ctxt
,
fs
,
uint32
(
4
+
2
*
SysArch
.
PtrSize
+
len
(
deltaBuf
)))
// length (excludes itself)
Adduint32
(
ctxt
,
fs
,
uint32
(
4
+
2
*
SysArch
.
PtrSize
+
len
(
deltaBuf
)))
// length (excludes itself)
if
Linkmode
==
LinkExternal
{
if
Linkmode
==
LinkExternal
{
adddwarfref
(
ctxt
,
fs
,
f
ramesec
,
4
)
adddwarfref
(
ctxt
,
fs
,
f
s
,
4
)
}
else
{
}
else
{
Adduint32
(
ctxt
,
fs
,
0
)
// CIE offset
Adduint32
(
ctxt
,
fs
,
0
)
// CIE offset
}
}
...
@@ -1292,27 +1275,24 @@ func writeframes(ctxt *Link, syms []*Symbol) []*Symbol {
...
@@ -1292,27 +1275,24 @@ func writeframes(ctxt *Link, syms []*Symbol) []*Symbol {
}
}
func
writeranges
(
ctxt
*
Link
,
syms
[]
*
Symbol
)
[]
*
Symbol
{
func
writeranges
(
ctxt
*
Link
,
syms
[]
*
Symbol
)
[]
*
Symbol
{
if
rangesec
==
nil
{
empty
:=
true
rangesec
=
ctxt
.
Syms
.
Lookup
(
".debug_ranges"
,
0
)
}
rangesec
.
Type
=
SDWARFSECT
rangesec
.
Attr
|=
AttrReachable
rangesec
.
R
=
rangesec
.
R
[
:
0
]
for
_
,
s
:=
range
ctxt
.
Textp
{
for
_
,
s
:=
range
ctxt
.
Textp
{
rangeSym
:=
ctxt
.
Syms
.
Lookup
(
dwarf
.
RangePrefix
+
s
.
Name
,
int
(
s
.
Version
))
rangeSym
:=
ctxt
.
Syms
.
Lookup
(
dwarf
.
RangePrefix
+
s
.
Name
,
int
(
s
.
Version
))
rangeSym
.
Attr
|=
AttrReachable
if
rangeSym
.
Size
==
0
{
rangeSym
.
Type
=
SDWARFRANGE
continue
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
rangeSym
.
Attr
|=
AttrReachable
|
AttrNotInSymbolTable
rangeSym
.
Type
=
SDWARFRANGE
syms
=
append
(
syms
,
rangeSym
)
empty
=
false
}
}
if
rangesec
.
Size
>
0
{
if
!
empty
{
// PE does not like empty sections
// PE does not like empty sections
rangesec
:=
ctxt
.
Syms
.
Lookup
(
".debug_ranges"
,
0
)
rangesec
.
Type
=
SDWARFRANGE
rangesec
.
Attr
|=
AttrReachable
rangesec
.
R
=
rangesec
.
R
[
:
0
]
syms
=
append
(
syms
,
rangesec
)
syms
=
append
(
syms
,
rangesec
)
}
}
return
syms
return
syms
...
@@ -1325,18 +1305,14 @@ const (
...
@@ -1325,18 +1305,14 @@ const (
COMPUNITHEADERSIZE
=
4
+
2
+
4
+
1
COMPUNITHEADERSIZE
=
4
+
2
+
4
+
1
)
)
func
writeinfo
(
ctxt
*
Link
,
syms
[]
*
Symbol
,
funcs
[]
*
Symbol
)
[]
*
Symbol
{
func
writeinfo
(
ctxt
*
Link
,
syms
[]
*
Symbol
,
funcs
[]
*
Symbol
,
abbrevsym
*
Symbol
)
[]
*
Symbol
{
if
infosec
==
nil
{
infosec
:=
ctxt
.
Syms
.
Lookup
(
".debug_info"
,
0
)
infosec
=
ctxt
.
Syms
.
Lookup
(
".debug_info"
,
0
)
}
infosec
.
R
=
infosec
.
R
[
:
0
]
infosec
.
R
=
infosec
.
R
[
:
0
]
infosec
.
Type
=
SDWARFINFO
infosec
.
Type
=
SDWARFINFO
infosec
.
Attr
|=
AttrReachable
infosec
.
Attr
|=
AttrReachable
syms
=
append
(
syms
,
infosec
)
syms
=
append
(
syms
,
infosec
)
if
arangessec
==
nil
{
arangessec
:=
ctxt
.
Syms
.
Lookup
(
".dwarfaranges"
,
0
)
arangessec
=
ctxt
.
Syms
.
Lookup
(
".dwarfaranges"
,
0
)
}
arangessec
.
R
=
arangessec
.
R
[
:
0
]
arangessec
.
R
=
arangessec
.
R
[
:
0
]
var
dwarfctxt
dwarf
.
Context
=
dwctxt
{
ctxt
}
var
dwarfctxt
dwarf
.
Context
=
dwctxt
{
ctxt
}
...
@@ -1577,10 +1553,10 @@ func dwarfgeneratedebugsyms(ctxt *Link) {
...
@@ -1577,10 +1553,10 @@ func dwarfgeneratedebugsyms(ctxt *Link) {
genasmsym
(
ctxt
,
defdwsymb
)
genasmsym
(
ctxt
,
defdwsymb
)
syms
:=
writeabbrev
(
ctxt
,
nil
)
abbrev
:=
writeabbrev
(
ctxt
)
syms
:=
[]
*
Symbol
{
abbrev
}
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
)
...
@@ -1596,16 +1572,42 @@ func dwarfgeneratedebugsyms(ctxt *Link) {
...
@@ -1596,16 +1572,42 @@ func dwarfgeneratedebugsyms(ctxt *Link) {
// Need to reorder symbols so SDWARFINFO is after all SDWARFSECT
// Need to reorder symbols so SDWARFINFO is after all SDWARFSECT
// (but we need to generate dies before writepub)
// (but we need to generate dies before writepub)
infosyms
:=
writeinfo
(
ctxt
,
nil
,
funcs
)
infosyms
:=
writeinfo
(
ctxt
,
nil
,
funcs
,
abbrev
)
syms
=
writepub
(
ctxt
,
".debug_pubnames"
,
ispubname
,
syms
)
syms
=
writepub
(
ctxt
,
".debug_pubnames"
,
ispubname
,
syms
)
syms
=
writepub
(
ctxt
,
".debug_pubtypes"
,
ispubtype
,
syms
)
syms
=
writepub
(
ctxt
,
".debug_pubtypes"
,
ispubtype
,
syms
)
syms
=
writearanges
(
ctxt
,
syms
)
syms
=
writearanges
(
ctxt
,
syms
)
syms
=
writegdbscript
(
ctxt
,
syms
)
syms
=
writegdbscript
(
ctxt
,
syms
)
syms
=
append
(
syms
,
infosyms
...
)
syms
=
append
(
syms
,
infosyms
...
)
syms
=
collectlocs
(
ctxt
,
syms
,
funcs
)
syms
=
writeranges
(
ctxt
,
syms
)
dwarfp
=
syms
dwarfp
=
syms
}
}
func
collectlocs
(
ctxt
*
Link
,
syms
[]
*
Symbol
,
funcs
[]
*
Symbol
)
[]
*
Symbol
{
empty
:=
true
for
_
,
fn
:=
range
funcs
{
for
_
,
reloc
:=
range
fn
.
R
{
if
reloc
.
Type
==
objabi
.
R_DWARFREF
&&
strings
.
HasPrefix
(
reloc
.
Sym
.
Name
,
dwarf
.
LocPrefix
)
{
reloc
.
Sym
.
Attr
|=
AttrReachable
|
AttrNotInSymbolTable
syms
=
append
(
syms
,
reloc
.
Sym
)
empty
=
false
// One location list entry per function, but many relocations to it. Don't duplicate.
break
}
}
}
// Don't emit .debug_loc if it's empty -- it makes the ARM linker mad.
if
!
empty
{
locsym
:=
ctxt
.
Syms
.
Lookup
(
".debug_loc"
,
0
)
locsym
.
R
=
locsym
.
R
[
:
0
]
locsym
.
Type
=
SDWARFLOC
locsym
.
Attr
|=
AttrReachable
syms
=
append
(
syms
,
locsym
)
}
return
syms
}
/*
/*
* Elf.
* Elf.
*/
*/
...
@@ -1618,6 +1620,7 @@ func dwarfaddshstrings(ctxt *Link, shstrtab *Symbol) {
...
@@ -1618,6 +1620,7 @@ func dwarfaddshstrings(ctxt *Link, shstrtab *Symbol) {
Addstring
(
shstrtab
,
".debug_aranges"
)
Addstring
(
shstrtab
,
".debug_aranges"
)
Addstring
(
shstrtab
,
".debug_frame"
)
Addstring
(
shstrtab
,
".debug_frame"
)
Addstring
(
shstrtab
,
".debug_info"
)
Addstring
(
shstrtab
,
".debug_info"
)
Addstring
(
shstrtab
,
".debug_loc"
)
Addstring
(
shstrtab
,
".debug_line"
)
Addstring
(
shstrtab
,
".debug_line"
)
Addstring
(
shstrtab
,
".debug_pubnames"
)
Addstring
(
shstrtab
,
".debug_pubnames"
)
Addstring
(
shstrtab
,
".debug_pubtypes"
)
Addstring
(
shstrtab
,
".debug_pubtypes"
)
...
@@ -1625,6 +1628,7 @@ func dwarfaddshstrings(ctxt *Link, shstrtab *Symbol) {
...
@@ -1625,6 +1628,7 @@ func dwarfaddshstrings(ctxt *Link, shstrtab *Symbol) {
Addstring
(
shstrtab
,
".debug_ranges"
)
Addstring
(
shstrtab
,
".debug_ranges"
)
if
Linkmode
==
LinkExternal
{
if
Linkmode
==
LinkExternal
{
Addstring
(
shstrtab
,
elfRelType
+
".debug_info"
)
Addstring
(
shstrtab
,
elfRelType
+
".debug_info"
)
Addstring
(
shstrtab
,
elfRelType
+
".debug_loc"
)
Addstring
(
shstrtab
,
elfRelType
+
".debug_aranges"
)
Addstring
(
shstrtab
,
elfRelType
+
".debug_aranges"
)
Addstring
(
shstrtab
,
elfRelType
+
".debug_line"
)
Addstring
(
shstrtab
,
elfRelType
+
".debug_line"
)
Addstring
(
shstrtab
,
elfRelType
+
".debug_frame"
)
Addstring
(
shstrtab
,
elfRelType
+
".debug_frame"
)
...
@@ -1651,6 +1655,10 @@ func dwarfaddelfsectionsyms(ctxt *Link) {
...
@@ -1651,6 +1655,10 @@ 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_loc"
,
0
)
if
sym
.
Sect
!=
nil
{
putelfsectionsym
(
sym
,
sym
.
Sect
.
Elfsect
.
shnum
)
}
sym
=
ctxt
.
Syms
.
Lookup
(
".debug_ranges"
,
0
)
sym
=
ctxt
.
Syms
.
Lookup
(
".debug_ranges"
,
0
)
if
sym
.
Sect
!=
nil
{
if
sym
.
Sect
!=
nil
{
putelfsectionsym
(
sym
,
sym
.
Sect
.
Elfsect
.
shnum
)
putelfsectionsym
(
sym
,
sym
.
Sect
.
Elfsect
.
shnum
)
...
...
src/cmd/link/internal/ld/elf.go
View file @
385cd668
...
@@ -1808,7 +1808,7 @@ func elfrelocsect(ctxt *Link, sect *Section, syms []*Symbol) {
...
@@ -1808,7 +1808,7 @@ func elfrelocsect(ctxt *Link, sect *Section, syms []*Symbol) {
continue
continue
}
}
if
r
.
Xsym
==
nil
{
if
r
.
Xsym
==
nil
{
Errorf
(
sym
,
"missing xsym in relocation
"
)
Errorf
(
sym
,
"missing xsym in relocation
%#v %#v"
,
r
.
Sym
.
Name
,
sym
)
continue
continue
}
}
if
r
.
Xsym
.
ElfsymForReloc
()
==
0
{
if
r
.
Xsym
.
ElfsymForReloc
()
==
0
{
...
@@ -2596,12 +2596,9 @@ elfobj:
...
@@ -2596,12 +2596,9 @@ elfobj:
elfshreloc
(
sect
)
elfshreloc
(
sect
)
}
}
for
_
,
s
:=
range
dwarfp
{
for
_
,
s
:=
range
dwarfp
{
if
len
(
s
.
R
)
>
0
||
s
.
Type
==
SDWARFINFO
{
if
len
(
s
.
R
)
>
0
||
s
.
Type
==
SDWARFINFO
||
s
.
Type
==
SDWARFLOC
{
elfshreloc
(
s
.
Sect
)
elfshreloc
(
s
.
Sect
)
}
}
if
s
.
Type
==
SDWARFINFO
{
break
}
}
}
// add a .note.GNU-stack section to mark the stack as non-executable
// add a .note.GNU-stack section to mark the stack as non-executable
sh
:=
elfshname
(
".note.GNU-stack"
)
sh
:=
elfshname
(
".note.GNU-stack"
)
...
...
src/cmd/link/internal/ld/symkind.go
View file @
385cd668
...
@@ -105,6 +105,7 @@ const (
...
@@ -105,6 +105,7 @@ const (
SDWARFSECT
SDWARFSECT
SDWARFINFO
SDWARFINFO
SDWARFRANGE
SDWARFRANGE
SDWARFLOC
SSUB
=
SymKind
(
1
<<
8
)
SSUB
=
SymKind
(
1
<<
8
)
SMASK
=
SymKind
(
SSUB
-
1
)
SMASK
=
SymKind
(
SSUB
-
1
)
SHIDDEN
=
SymKind
(
1
<<
9
)
SHIDDEN
=
SymKind
(
1
<<
9
)
...
@@ -124,6 +125,7 @@ var abiSymKindToSymKind = [...]SymKind{
...
@@ -124,6 +125,7 @@ var abiSymKindToSymKind = [...]SymKind{
STLSBSS
,
STLSBSS
,
SDWARFINFO
,
SDWARFINFO
,
SDWARFRANGE
,
SDWARFRANGE
,
SDWARFLOC
,
}
}
// readOnly are the symbol kinds that form read-only sections. In some
// readOnly are the symbol kinds that form read-only sections. In some
...
...
src/cmd/link/internal/ld/symkind_string.go
View file @
385cd668
...
@@ -4,9 +4,9 @@ package ld
...
@@ -4,9 +4,9 @@ package ld
import
"fmt"
import
"fmt"
const
_SymKind_name
=
"SxxxSTEXTSELFRXSECTSTYPESSTRINGSGOSTRINGSGOFUNCSGCBITSSRODATASFUNCTABSELFROSECTSMACHOPLTSTYPERELROSSTRINGRELROSGOSTRINGRELROSGOFUNCRELROSGCBITSRELROSRODATARELROSFUNCTABRELROSTYPELINKSITABLINKSSYMTABSPCLNTABSELFSECTSMACHOSMACHOGOTSWINDOWSSELFGOTSNOPTRDATASINITARRSDATASBSSSNOPTRBSSSTLSBSSSXREFSMACHOSYMSTRSMACHOSYMTABSMACHOINDIRECTPLTSMACHOINDIRECTGOTSFILESFILEPATHSCONSTSDYNIMPORTSHOSTOBJSDWARFSECTSDWARFINFOSDWARFRANGE"
const
_SymKind_name
=
"SxxxSTEXTSELFRXSECTSTYPESSTRINGSGOSTRINGSGOFUNCSGCBITSSRODATASFUNCTABSELFROSECTSMACHOPLTSTYPERELROSSTRINGRELROSGOSTRINGRELROSGOFUNCRELROSGCBITSRELROSRODATARELROSFUNCTABRELROSTYPELINKSITABLINKSSYMTABSPCLNTABSELFSECTSMACHOSMACHOGOTSWINDOWSSELFGOTSNOPTRDATASINITARRSDATASBSSSNOPTRBSSSTLSBSSSXREFSMACHOSYMSTRSMACHOSYMTABSMACHOINDIRECTPLTSMACHOINDIRECTGOTSFILESFILEPATHSCONSTSDYNIMPORTSHOSTOBJSDWARFSECTSDWARFINFOSDWARFRANGE
SDWARFLOC
"
var
_SymKind_index
=
[
...
]
uint16
{
0
,
4
,
9
,
19
,
24
,
31
,
40
,
47
,
54
,
61
,
69
,
79
,
88
,
98
,
110
,
124
,
136
,
148
,
160
,
173
,
182
,
191
,
198
,
206
,
214
,
220
,
229
,
237
,
244
,
254
,
262
,
267
,
271
,
280
,
287
,
292
,
304
,
316
,
333
,
350
,
355
,
364
,
370
,
380
,
388
,
398
,
408
,
419
}
var
_SymKind_index
=
[
...
]
uint16
{
0
,
4
,
9
,
19
,
24
,
31
,
40
,
47
,
54
,
61
,
69
,
79
,
88
,
98
,
110
,
124
,
136
,
148
,
160
,
173
,
182
,
191
,
198
,
206
,
214
,
220
,
229
,
237
,
244
,
254
,
262
,
267
,
271
,
280
,
287
,
292
,
304
,
316
,
333
,
350
,
355
,
364
,
370
,
380
,
388
,
398
,
408
,
419
,
428
}
func
(
i
SymKind
)
String
()
string
{
func
(
i
SymKind
)
String
()
string
{
if
i
<
0
||
i
>=
SymKind
(
len
(
_SymKind_index
)
-
1
)
{
if
i
<
0
||
i
>=
SymKind
(
len
(
_SymKind_index
)
-
1
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment