Skip to content

Commit 175c321

Browse files
Merge branch 'golang:master' into master
2 parents 118287e + 71c2bf5 commit 175c321

File tree

28 files changed

+320
-95
lines changed

28 files changed

+320
-95
lines changed

src/cmd/compile/internal/dwarfgen/dwarf.go

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -248,11 +248,6 @@ func createDwarfVars(fnsym *obj.LSym, complexOK bool, fn *ir.Func, apDecls []*ir
248248
if n.Class == ir.PPARAM || n.Class == ir.PPARAMOUT {
249249
tag = dwarf.DW_TAG_formal_parameter
250250
}
251-
if n.Esc() == ir.EscHeap {
252-
// The variable in question has been promoted to the heap.
253-
// Its address is in n.Heapaddr.
254-
// TODO(thanm): generate a better location expression
255-
}
256251
inlIndex := 0
257252
if base.Flag.GenDwarfInl > 1 {
258253
if n.InlFormal() || n.InlLocal() {
@@ -263,7 +258,7 @@ func createDwarfVars(fnsym *obj.LSym, complexOK bool, fn *ir.Func, apDecls []*ir
263258
}
264259
}
265260
declpos := base.Ctxt.InnermostPos(n.Pos())
266-
vars = append(vars, &dwarf.Var{
261+
dvar := &dwarf.Var{
267262
Name: n.Sym().Name,
268263
IsReturnValue: isReturnValue,
269264
Tag: tag,
@@ -277,8 +272,19 @@ func createDwarfVars(fnsym *obj.LSym, complexOK bool, fn *ir.Func, apDecls []*ir
277272
ChildIndex: -1,
278273
DictIndex: n.DictIndex,
279274
ClosureOffset: closureOffset(n, closureVars),
280-
})
281-
// Record go type of to insure that it gets emitted by the linker.
275+
}
276+
if n.Esc() == ir.EscHeap {
277+
if n.Heapaddr == nil {
278+
base.Fatalf("invalid heap allocated var without Heapaddr")
279+
}
280+
debug := fn.DebugInfo.(*ssa.FuncDebug)
281+
list := createHeapDerefLocationList(n, fnsym, debug.EntryID, ssa.FuncEnd.ID)
282+
dvar.PutLocationList = func(listSym, startPC dwarf.Sym) {
283+
debug.PutLocationList(list, base.Ctxt, listSym.(*obj.LSym), startPC.(*obj.LSym))
284+
}
285+
}
286+
vars = append(vars, dvar)
287+
// Record go type to ensure that it gets emitted by the linker.
282288
fnsym.Func().RecordAutoType(reflectdata.TypeLinksym(n.Type()))
283289
}
284290

@@ -550,6 +556,29 @@ func createComplexVar(fnsym *obj.LSym, fn *ir.Func, varID ssa.VarID, closureVars
550556
return dvar
551557
}
552558

559+
// createHeapDerefLocationList creates a location list for a heap-escaped variable
560+
// that describes "dereference pointer at stack offset"
561+
func createHeapDerefLocationList(n *ir.Name, fnsym *obj.LSym, entryID, prologEndID ssa.ID) []byte {
562+
// Get the stack offset where the heap pointer is stored
563+
heapPtrOffset := n.Heapaddr.FrameOffset()
564+
if base.Ctxt.Arch.FixedFrameSize == 0 {
565+
heapPtrOffset -= int64(types.PtrSize)
566+
}
567+
if buildcfg.FramePointerEnabled {
568+
heapPtrOffset -= int64(types.PtrSize)
569+
}
570+
571+
// Create a location expression: DW_OP_fbreg <offset> DW_OP_deref
572+
var locExpr []byte
573+
var sizeIdx int
574+
locExpr, sizeIdx = ssa.SetupLocList(base.Ctxt, entryID, locExpr, ssa.BlockStart.ID, ssa.FuncEnd.ID)
575+
locExpr = append(locExpr, dwarf.DW_OP_fbreg)
576+
locExpr = dwarf.AppendSleb128(locExpr, heapPtrOffset)
577+
locExpr = append(locExpr, dwarf.DW_OP_deref)
578+
base.Ctxt.Arch.ByteOrder.PutUint16(locExpr[sizeIdx:], uint16(len(locExpr)-sizeIdx-2))
579+
return locExpr
580+
}
581+
553582
// RecordFlags records the specified command-line flags to be placed
554583
// in the DWARF info.
555584
func RecordFlags(flags ...string) {

src/cmd/compile/internal/ssa/debug.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ type FuncDebug struct {
4141
RegOutputParams []*ir.Name
4242
// Variable declarations that were removed during optimization
4343
OptDcl []*ir.Name
44+
// The ssa.Func.EntryID value, used to build location lists for
45+
// return values promoted to heap in later DWARF generation.
46+
EntryID ID
4447

4548
// Filled in by the user. Translates Block and Value ID to PC.
4649
//
@@ -1645,13 +1648,13 @@ func readPtr(ctxt *obj.Link, buf []byte) uint64 {
16451648

16461649
}
16471650

1648-
// setupLocList creates the initial portion of a location list for a
1651+
// SetupLocList creates the initial portion of a location list for a
16491652
// user variable. It emits the encoded start/end of the range and a
16501653
// placeholder for the size. Return value is the new list plus the
16511654
// slot in the list holding the size (to be updated later).
1652-
func setupLocList(ctxt *obj.Link, f *Func, list []byte, st, en ID) ([]byte, int) {
1653-
start, startOK := encodeValue(ctxt, f.Entry.ID, st)
1654-
end, endOK := encodeValue(ctxt, f.Entry.ID, en)
1655+
func SetupLocList(ctxt *obj.Link, entryID ID, list []byte, st, en ID) ([]byte, int) {
1656+
start, startOK := encodeValue(ctxt, entryID, st)
1657+
end, endOK := encodeValue(ctxt, entryID, en)
16551658
if !startOK || !endOK {
16561659
// This could happen if someone writes a function that uses
16571660
// >65K values on a 32-bit platform. Hopefully a degraded debugging
@@ -1800,7 +1803,6 @@ func isNamedRegParam(p abi.ABIParamAssignment) bool {
18001803
// appropriate for the ".closureptr" compiler-synthesized variable
18011804
// needed by the debugger for range func bodies.
18021805
func BuildFuncDebugNoOptimized(ctxt *obj.Link, f *Func, loggingEnabled bool, stackOffset func(LocalSlot) int32, rval *FuncDebug) {
1803-
18041806
needCloCtx := f.CloSlot != nil
18051807
pri := f.ABISelf.ABIAnalyzeFuncType(f.Type)
18061808

@@ -1911,7 +1913,7 @@ func BuildFuncDebugNoOptimized(ctxt *obj.Link, f *Func, loggingEnabled bool, sta
19111913
// Param is arriving in one or more registers. We need a 2-element
19121914
// location expression for it. First entry in location list
19131915
// will correspond to lifetime in input registers.
1914-
list, sizeIdx := setupLocList(ctxt, f, rval.LocationLists[pidx],
1916+
list, sizeIdx := SetupLocList(ctxt, f.Entry.ID, rval.LocationLists[pidx],
19151917
BlockStart.ID, afterPrologVal)
19161918
if list == nil {
19171919
pidx++
@@ -1961,7 +1963,7 @@ func BuildFuncDebugNoOptimized(ctxt *obj.Link, f *Func, loggingEnabled bool, sta
19611963

19621964
// Second entry in the location list will be the stack home
19631965
// of the param, once it has been spilled. Emit that now.
1964-
list, sizeIdx = setupLocList(ctxt, f, list,
1966+
list, sizeIdx = SetupLocList(ctxt, f.Entry.ID, list,
19651967
afterPrologVal, FuncEnd.ID)
19661968
if list == nil {
19671969
pidx++

src/cmd/compile/internal/ssa/debug_lines_test.go

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -116,20 +116,30 @@ func TestDebugLines_53456(t *testing.T) {
116116
}
117117

118118
func TestDebugLines_74576(t *testing.T) {
119-
tests := []struct {
120-
file string
121-
wantStmts []int
122-
}{
123-
{"i74576a.go", []int{12, 13, 13, 14}},
124-
{"i74576b.go", []int{12, 13, 13, 14}},
125-
{"i74576c.go", []int{12, 13, 13, 14}},
126-
}
127-
t.Parallel()
128-
for _, test := range tests {
129-
t.Run(test.file, func(t *testing.T) {
130-
t.Parallel()
131-
testDebugLines(t, "-N -l", test.file, "main", test.wantStmts, false)
132-
})
119+
unixOnly(t)
120+
121+
switch testGoArch() {
122+
default:
123+
// Failed on linux/riscv64 (issue 74669), but conservatively
124+
// skip many architectures like several other tests here.
125+
t.Skip("skipped for many architectures")
126+
127+
case "arm64", "amd64", "loong64":
128+
tests := []struct {
129+
file string
130+
wantStmts []int
131+
}{
132+
{"i74576a.go", []int{12, 13, 13, 14}},
133+
{"i74576b.go", []int{12, 13, 13, 14}},
134+
{"i74576c.go", []int{12, 13, 13, 14}},
135+
}
136+
t.Parallel()
137+
for _, test := range tests {
138+
t.Run(test.file, func(t *testing.T) {
139+
t.Parallel()
140+
testDebugLines(t, "-N -l", test.file, "main", test.wantStmts, false)
141+
})
142+
}
133143
}
134144
}
135145

src/cmd/compile/internal/ssagen/ssa.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7607,6 +7607,9 @@ func genssa(f *ssa.Func, pp *objw.Progs) {
76077607
if base.Ctxt.Flag_locationlists {
76087608
var debugInfo *ssa.FuncDebug
76097609
debugInfo = e.curfn.DebugInfo.(*ssa.FuncDebug)
7610+
// Save off entry ID in case we need it later for DWARF generation
7611+
// for return values promoted to the heap.
7612+
debugInfo.EntryID = f.Entry.ID
76107613
if e.curfn.ABI == obj.ABIInternal && base.Flag.N != 0 {
76117614
ssa.BuildFuncDebugNoOptimized(base.Ctxt, f, base.Debug.LocationLists > 1, StackOffset, debugInfo)
76127615
} else {

src/cmd/compile/internal/types2/builtins.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,22 +91,25 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
9191
// to type []byte with a second argument of string type followed by ... .
9292
// This form appends the bytes of the string."
9393

94-
// get special case out of the way
94+
// Handle append(bytes, y...) special case, where
95+
// the type set of y is {string} or {string, []byte}.
9596
var sig *Signature
9697
if nargs == 2 && hasDots(call) {
9798
if ok, _ := x.assignableTo(check, NewSlice(universeByte), nil); ok {
9899
y := args[1]
100+
hasString := false
99101
typeset(y.typ, func(_, u Type) bool {
100102
if s, _ := u.(*Slice); s != nil && Identical(s.elem, universeByte) {
101103
return true
102104
}
103105
if isString(u) {
106+
hasString = true
104107
return true
105108
}
106109
y = nil
107110
return false
108111
})
109-
if y != nil {
112+
if y != nil && hasString {
110113
// setting the signature also signals that we're done
111114
sig = makeSig(x.typ, x.typ, y.typ)
112115
sig.variadic = true

src/cmd/go/internal/base/base.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,11 @@ var Go = &Command{
6262
// Lookup returns the subcommand with the given name, if any.
6363
// Otherwise it returns nil.
6464
//
65-
// Lookup ignores subcommands that have len(c.Commands) == 0 and c.Run == nil.
65+
// Lookup ignores any subcommand `sub` that has len(sub.Commands) == 0 and sub.Run == nil.
6666
// Such subcommands are only for use as arguments to "help".
6767
func (c *Command) Lookup(name string) *Command {
6868
for _, sub := range c.Commands {
69-
if sub.Name() == name && (len(c.Commands) > 0 || c.Runnable()) {
69+
if sub.Name() == name && (len(sub.Commands) > 0 || sub.Runnable()) {
7070
return sub
7171
}
7272
}

src/cmd/internal/obj/arm64/obj7.go

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -907,18 +907,49 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
907907
p.To.Reg = REGFP
908908
p.To.Offset = REGLINK
909909

910-
// ADD $aoffset, RSP, RSP
911-
q = newprog()
912-
q.As = AADD
913-
q.From.Type = obj.TYPE_CONST
914-
q.From.Offset = int64(aoffset)
915-
q.To.Type = obj.TYPE_REG
916-
q.To.Reg = REGSP
917-
q.Spadj = -aoffset
918-
q.Pos = p.Pos
919-
q.Link = p.Link
920-
p.Link = q
921-
p = q
910+
if aoffset < 1<<12 {
911+
// ADD $aoffset, RSP, RSP
912+
q = newprog()
913+
q.As = AADD
914+
q.From.Type = obj.TYPE_CONST
915+
q.From.Offset = int64(aoffset)
916+
q.To.Type = obj.TYPE_REG
917+
q.To.Reg = REGSP
918+
q.Spadj = -aoffset
919+
q.Pos = p.Pos
920+
q.Link = p.Link
921+
p.Link = q
922+
p = q
923+
} else {
924+
// Put frame size in a separate register and
925+
// add it in with a single instruction,
926+
// so we never have a partial frame during
927+
// the epilog. See issue 73259.
928+
929+
// MOVD $aoffset, REGTMP
930+
q = newprog()
931+
q.As = AMOVD
932+
q.From.Type = obj.TYPE_CONST
933+
q.From.Offset = int64(aoffset)
934+
q.To.Type = obj.TYPE_REG
935+
q.To.Reg = REGTMP
936+
q.Pos = p.Pos
937+
q.Link = p.Link
938+
p.Link = q
939+
p = q
940+
// ADD REGTMP, RSP, RSP
941+
q = newprog()
942+
q.As = AADD
943+
q.From.Type = obj.TYPE_REG
944+
q.From.Reg = REGTMP
945+
q.To.Type = obj.TYPE_REG
946+
q.To.Reg = REGSP
947+
q.Spadj = -aoffset
948+
q.Pos = p.Pos
949+
q.Link = p.Link
950+
p.Link = q
951+
p = q
952+
}
922953
}
923954

924955
// If enabled, this code emits 'MOV PC, R27' before every 'MOV LR, PC',

src/cmd/internal/obj/fips140.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,7 @@ func (s *LSym) checkFIPSReloc(ctxt *Link, rel Reloc) {
384384
objabi.R_RISCV_TLS_IE,
385385
objabi.R_RISCV_TLS_LE,
386386
objabi.R_RISCV_GOT_HI20,
387+
objabi.R_RISCV_GOT_PCREL_ITYPE,
387388
objabi.R_RISCV_PCREL_HI20,
388389
objabi.R_RISCV_PCREL_LO12_I,
389390
objabi.R_RISCV_PCREL_LO12_S,

src/cmd/internal/objabi/reloctype.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ func (r RelocType) IsDwTxtAddr() bool {
466466
// FuncCountToDwTxtAddrFlavor returns the correct DWARF .debug_addr
467467
// section relocation to use when compiling a package with a total of
468468
// fncount functions, along with the size of the ULEB128-encoded blob
469-
// needed to store the the eventual .debug_addr index.
469+
// needed to store the eventual .debug_addr index.
470470
func FuncCountToDwTxtAddrFlavor(fncount int) (RelocType, int) {
471471
switch {
472472
case fncount <= 127:

0 commit comments

Comments
 (0)