|
5 | 5 | package ld
|
6 | 6 |
|
7 | 7 | import (
|
| 8 | + "bytes" |
8 | 9 | "debug/dwarf"
|
| 10 | + "debug/elf" |
9 | 11 | "debug/pe"
|
10 | 12 | "fmt"
|
11 | 13 | "internal/platform"
|
@@ -2042,3 +2044,118 @@ func TestConsistentGoKindAndRuntimeType(t *testing.T) {
|
2042 | 2044 | t.Logf("%d types checked\n", typesChecked)
|
2043 | 2045 | }
|
2044 | 2046 | }
|
| 2047 | + |
| 2048 | +func TestIssue72053(t *testing.T) { |
| 2049 | + testenv.MustHaveGoBuild(t) |
| 2050 | + |
| 2051 | + mustHaveDWARF(t) |
| 2052 | + |
| 2053 | + t.Parallel() |
| 2054 | + |
| 2055 | + dir := t.TempDir() |
| 2056 | + |
| 2057 | + const prog = `package main |
| 2058 | +
|
| 2059 | +import ( |
| 2060 | + "fmt" |
| 2061 | + "strings" |
| 2062 | +) |
| 2063 | +
|
| 2064 | +func main() { |
| 2065 | + u := Address{Addr: "127.0.0.1"} |
| 2066 | + fmt.Println(u) // line 10 |
| 2067 | +} |
| 2068 | +
|
| 2069 | +type Address struct { |
| 2070 | + TLS bool |
| 2071 | + Addr string |
| 2072 | +} |
| 2073 | +
|
| 2074 | +func (a Address) String() string { |
| 2075 | + sb := new(strings.Builder) |
| 2076 | + sb.WriteString(a.Addr) |
| 2077 | + return sb.String() |
| 2078 | +} |
| 2079 | +` |
| 2080 | + |
| 2081 | + bf := gobuild(t, dir, prog, NoOpt) |
| 2082 | + |
| 2083 | + defer bf.Close() |
| 2084 | + |
| 2085 | + f, err := elf.Open(bf.path) |
| 2086 | + if err != nil { |
| 2087 | + t.Fatal(err) |
| 2088 | + } |
| 2089 | + |
| 2090 | + dwrf, err := f.DWARF() |
| 2091 | + if err != nil { |
| 2092 | + t.Fatal(err) |
| 2093 | + } |
| 2094 | + s := f.Section(".debug_loc") |
| 2095 | + data, err := s.Data() |
| 2096 | + if err != nil { |
| 2097 | + t.Fatal(err) |
| 2098 | + } |
| 2099 | + if err := dwrf.AddSection(".debug_loc", data); err != nil { |
| 2100 | + t.Fatal(err) |
| 2101 | + } |
| 2102 | + |
| 2103 | + rdr := dwrf.Reader() |
| 2104 | + |
| 2105 | + for { |
| 2106 | + e, err := rdr.Next() |
| 2107 | + if err != nil { |
| 2108 | + t.Fatal(err) |
| 2109 | + } |
| 2110 | + if e == nil { |
| 2111 | + break |
| 2112 | + } |
| 2113 | + |
| 2114 | + name, _ := e.Val(dwarf.AttrName).(string) |
| 2115 | + |
| 2116 | + switch e.Tag { |
| 2117 | + case dwarf.TagSubprogram: |
| 2118 | + if name == "main.Address.String" { |
| 2119 | + for { |
| 2120 | + e, err := rdr.Next() |
| 2121 | + if err != nil || e == nil { |
| 2122 | + break |
| 2123 | + } |
| 2124 | + name, _ := e.Val(dwarf.AttrName).(string) |
| 2125 | + if name == "a" { |
| 2126 | + loc := e.AttrField(dwarf.AttrLocation) |
| 2127 | + if loc != nil { |
| 2128 | + switch loc.Class { |
| 2129 | + case dwarf.ClassLocListPtr: |
| 2130 | + offset := loc.Val.(int64) |
| 2131 | + buf := make([]byte, 48) |
| 2132 | + s := f.Section(".debug_loc") |
| 2133 | + if s == nil { |
| 2134 | + t.Fatal("could not find debug_loc section") |
| 2135 | + } |
| 2136 | + d := s.Open() |
| 2137 | + d.Seek(offset, io.SeekStart) |
| 2138 | + d.Read(buf) |
| 2139 | + |
| 2140 | + // DW_OP_reg0 DW_OP_piece 0x1 DW_OP_piece 0x7 DW_OP_reg3 DW_OP_piece 0x8 DW_OP_piece 0x7 DW_OP_reg2 DW_OP_piece 0x8 |
| 2141 | + wrong := []byte{ |
| 2142 | + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
| 2143 | + 0xa0, 0x2c, 0x49, 0x0, 0x0, 0x0, 0x0, 0x0, |
| 2144 | + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, |
| 2145 | + 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, |
| 2146 | + 0xd, 0x0, 0x50, 0x93, 0x1, 0x93, 0x7, 0x53, |
| 2147 | + 0x93, 0x8, 0x93, 0x7, 0x52, 0x93, 0x8, 0x1f, |
| 2148 | + } |
| 2149 | + |
| 2150 | + if bytes.Equal(buf, wrong) { |
| 2151 | + t.Fatal("unexpected DWARF sequence found") |
| 2152 | + } |
| 2153 | + } |
| 2154 | + } |
| 2155 | + break |
| 2156 | + } |
| 2157 | + } |
| 2158 | + } |
| 2159 | + } |
| 2160 | + } |
| 2161 | +} |
0 commit comments