aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/link
diff options
context:
space:
mode:
authorThan McIntosh <thanm@google.com>2021-05-11 11:29:27 -0400
committerThan McIntosh <thanm@google.com>2021-05-13 14:30:42 +0000
commitfd4631e24f53cf836a67b00e82e2159854ec31d0 (patch)
tree8346620914ca381775dee01d279afe767fd5cf4b /src/cmd/link
parenta63cded5e413ffad1ec8088ef7abd10abb7b5252 (diff)
downloadgo-fd4631e24f53cf836a67b00e82e2159854ec31d0.tar.gz
go-fd4631e24f53cf836a67b00e82e2159854ec31d0.zip
cmd/compile/internal/dwarfgen: fix DWARF param DIE ordering
The DWARF standard requires that the DIEs in a subprogram corresponding to input and output parameters appear in declaration order; this patch adds some new code in dwarfgen to enforce this ordering (relying on the existing fn.Dcl ordering is not sufficient). Prior to the register ABI, it was easy to keep vars/decls sorted during DWARF generation since you could always rely on frame offset; with the ABI sorting by frame offset no longer gives you the original declaration order in all cases. Fixes #46055. Change-Id: I0e070cb781d6453caba896e5d3bee7cd5388050d Reviewed-on: https://go-review.googlesource.com/c/go/+/318829 Trust: Than McIntosh <thanm@google.com> Run-TryBot: Than McIntosh <thanm@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Alessandro Arzilli <alessandro.arzilli@gmail.com> Reviewed-by: Cherry Mui <cherryyz@google.com>
Diffstat (limited to 'src/cmd/link')
-rw-r--r--src/cmd/link/internal/ld/dwarf_test.go30
1 files changed, 17 insertions, 13 deletions
diff --git a/src/cmd/link/internal/ld/dwarf_test.go b/src/cmd/link/internal/ld/dwarf_test.go
index 5cc4800e2a..2f59c2fe0a 100644
--- a/src/cmd/link/internal/ld/dwarf_test.go
+++ b/src/cmd/link/internal/ld/dwarf_test.go
@@ -1660,16 +1660,16 @@ func TestOutputParamAbbrevAndAttr(t *testing.T) {
package main
//go:noinline
-func ABC(p1, p2, p3 int, f1, f2, f3 float32, b1 [1024]int) (r1 int, r2 int, r3 [1024]int, r4 byte) {
- b1[0] = 6
- r1, r2, r3, r4 = p3, p2, b1, 'a'
+func ABC(c1, c2, c3 int, d1, d2, d3, d4 string, f1, f2, f3 float32, g1 [1024]int) (r1 int, r2 int, r3 [1024]int, r4 byte, r5 string, r6 float32) {
+ g1[0] = 6
+ r1, r2, r3, r4, r5, r6 = c3, c2+c1, g1, 'a', d1+d2+d3+d4, f1+f2+f3
return
}
func main() {
a := [1024]int{}
- v1, v2, v3, v4 := ABC(1, 2, 3, 1.0, 2.0, 1.0, a)
- println(v1, v2, v3[0], v4)
+ v1, v2, v3, v4, v5, v6 := ABC(1, 2, 3, "a", "b", "c", "d", 1.0, 2.0, 1.0, a)
+ println(v1, v2, v3[0], v4, v5, v6)
}
`
dir := t.TempDir()
@@ -1708,18 +1708,20 @@ func main() {
// OK to have it missing for input parameters, but for the moment
// we verify that the attr is present but set to false.
- // Values in this map:
+ // Values in this map are of the form <order>:<varparam>
+ // where order is the order within the child DIE list of the param,
+ // and <varparam> is an integer:
//
- // 0: <no param of this name>
// -1: varparm attr not found
// 1: varparm found with value false
// 2: varparm found with value true
//
- foundParams := make(map[string]int)
+ foundParams := make(map[string]string)
// Walk ABCs's children looking for params.
abcIdx := ex.idxFromOffset(abcdie.Offset)
childDies := ex.Children(abcIdx)
+ idx := 0
for _, child := range childDies {
if child.Tag == dwarf.TagFormalParameter {
st := -1
@@ -1731,7 +1733,8 @@ func main() {
}
}
if name, ok := child.Val(dwarf.AttrName).(string); ok {
- foundParams[name] = st
+ foundParams[name] = fmt.Sprintf("%d:%d", idx, st)
+ idx++
}
}
}
@@ -1739,13 +1742,14 @@ func main() {
// Digest the result.
found := make([]string, 0, len(foundParams))
for k, v := range foundParams {
- found = append(found, fmt.Sprintf("%s:%d", k, v))
+ found = append(found, fmt.Sprintf("%s:%s", k, v))
}
sort.Strings(found)
- // Make sure we see all of the expected params, that they have
- // the varparam attr, and the varparm is set for the returns.
- expected := "[b1:1 f1:1 f2:1 f3:1 p1:1 p2:1 p3:1 r1:2 r2:2 r3:2 r4:2]"
+ // Make sure we see all of the expected params in the proper
+ // order, that they have the varparam attr, and the varparm is set
+ // for the returns.
+ expected := "[c1:0:1 c2:1:1 c3:2:1 d1:3:1 d2:4:1 d3:5:1 d4:6:1 f1:7:1 f2:8:1 f3:9:1 g1:10:1 r1:11:2 r2:12:2 r3:13:2 r4:14:2 r5:15:2 r6:16:2]"
if fmt.Sprintf("%+v", found) != expected {
t.Errorf("param check failed, wanted %s got %s\n",
expected, found)