package ld
import (
- "bytes"
"debug/dwarf"
- "debug/elf"
"debug/pe"
"fmt"
"internal/platform"
t.Logf("%d types checked\n", typesChecked)
}
}
-
-func TestIssue72053(t *testing.T) {
- if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
- t.Skip("skipping test: requires ELF binary and amd64 arch")
- }
-
- testenv.MustHaveGoBuild(t)
-
- mustHaveDWARF(t)
-
- t.Parallel()
-
- dir := t.TempDir()
-
- const prog = `package main
-
-import (
- "fmt"
- "strings"
-)
-
-func main() {
- u := Address{Addr: "127.0.0.1"}
- fmt.Println(u) // line 10
-}
-
-type Address struct {
- TLS bool
- Addr string
-}
-
-func (a Address) String() string {
- sb := new(strings.Builder)
- sb.WriteString(a.Addr)
- return sb.String()
-}
-`
-
- bf := gobuild(t, dir, prog, NoOpt)
-
- defer bf.Close()
-
- f, err := elf.Open(bf.path)
- if err != nil {
- t.Fatal(err)
- }
-
- dwrf, err := f.DWARF()
- if err != nil {
- t.Fatal(err)
- }
-
- rdr := dwrf.Reader()
-
- found := false
- for {
- e, err := rdr.Next()
- if err != nil {
- t.Fatal(err)
- }
- if e == nil {
- break
- }
-
- name, _ := e.Val(dwarf.AttrName).(string)
-
- if e.Tag == dwarf.TagSubprogram && name == "main.Address.String" {
- found = true
- continue
- }
-
- if found && name == "a" {
- loc := e.AttrField(dwarf.AttrLocation)
- if loc != nil {
- switch loc.Class {
- case dwarf.ClassLocListPtr:
- offset := loc.Val.(int64)
- buf := make([]byte, 32)
- s := f.Section(".debug_loc")
- if s == nil {
- t.Fatal("could not find debug_loc section")
- }
- d := s.Open()
- // Seek past the first 16 bytes which establishes the base address and
- // can be brittle and unreliable in the test due to compiler changes or DWARF
- // version used.
- d.Seek(offset+16, io.SeekStart)
- d.Read(buf)
-
- // DW_OP_reg0 DW_OP_piece 0x1 DW_OP_piece 0x7 DW_OP_reg3 DW_OP_piece 0x8 DW_OP_reg2 DW_OP_piece 0x8
- expected := []byte{
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x0b, 0x00, 0x50, 0x93, 0x01, 0x93, 0x07, 0x53,
- 0x93, 0x08, 0x52, 0x93, 0x08, 0x1f, 0x00, 0x00,
- }
-
- if !bytes.Equal(buf, expected) {
- t.Fatalf("unexpected DWARF sequence found, expected:\n%#v\nfound:\n%#v\n", expected, buf)
- }
- }
- } else {
- t.Fatal("unable to find expected DWARF location list")
- }
- break
- }
- }
- if !found {
- t.Fatal("unable to find expected DWARF location list")
- }
-}