Browse Source

Update vendors

pull/552/head
MZI 10 months ago
parent
commit
db6c162b03
No account linked to committer's email address
100 changed files with 19733 additions and 3761 deletions
  1. 24
    0
      vendor/github.com/cosiner/argv/LICENSE
  2. 34
    0
      vendor/github.com/cosiner/argv/argv.go
  3. 79
    0
      vendor/github.com/cosiner/argv/cmd.go
  4. 222
    0
      vendor/github.com/cosiner/argv/parser.go
  5. 282
    0
      vendor/github.com/cosiner/argv/scanner.go
  6. 0
    122
      vendor/github.com/derekparker/delve/dwarf/line/line_parser.go
  7. 0
    252
      vendor/github.com/derekparker/delve/dwarf/line/state_machine.go
  8. 0
    84
      vendor/github.com/derekparker/delve/dwarf/op/op.go
  9. 62
    15
      vendor/github.com/derekparker/delve/pkg/config/config.go
  10. 63
    0
      vendor/github.com/derekparker/delve/pkg/config/split.go
  11. 9
    27
      vendor/github.com/derekparker/delve/pkg/dwarf/frame/entries.go
  12. 0
    0
      vendor/github.com/derekparker/delve/pkg/dwarf/frame/expression_constants.go
  13. 18
    9
      vendor/github.com/derekparker/delve/pkg/dwarf/frame/parser.go
  14. 52
    57
      vendor/github.com/derekparker/delve/pkg/dwarf/frame/table.go
  15. 107
    0
      vendor/github.com/derekparker/delve/pkg/dwarf/godwarf/sections.go
  16. 124
    108
      vendor/github.com/derekparker/delve/pkg/dwarf/godwarf/type.go
  17. 152
    0
      vendor/github.com/derekparker/delve/pkg/dwarf/line/line_parser.go
  18. 450
    0
      vendor/github.com/derekparker/delve/pkg/dwarf/line/state_machine.go
  19. 197
    0
      vendor/github.com/derekparker/delve/pkg/dwarf/op/op.go
  20. 515
    0
      vendor/github.com/derekparker/delve/pkg/dwarf/op/opcodes.go
  21. 175
    0
      vendor/github.com/derekparker/delve/pkg/dwarf/op/opcodes.table
  22. 102
    0
      vendor/github.com/derekparker/delve/pkg/dwarf/op/regs.go
  23. 133
    32
      vendor/github.com/derekparker/delve/pkg/dwarf/reader/reader.go
  24. 114
    0
      vendor/github.com/derekparker/delve/pkg/dwarf/reader/variables.go
  25. 24
    76
      vendor/github.com/derekparker/delve/pkg/dwarf/util/buf.go
  26. 46
    1
      vendor/github.com/derekparker/delve/pkg/dwarf/util/util.go
  27. 178
    0
      vendor/github.com/derekparker/delve/pkg/goversion/go_version.go
  28. 83
    0
      vendor/github.com/derekparker/delve/pkg/logflags/logflags.go
  29. 306
    0
      vendor/github.com/derekparker/delve/pkg/proc/arch.go
  30. 878
    0
      vendor/github.com/derekparker/delve/pkg/proc/bininfo.go
  31. 437
    0
      vendor/github.com/derekparker/delve/pkg/proc/breakpoints.go
  32. 526
    0
      vendor/github.com/derekparker/delve/pkg/proc/core/core.go
  33. 556
    0
      vendor/github.com/derekparker/delve/pkg/proc/core/linux_amd64_core.go
  34. 121
    0
      vendor/github.com/derekparker/delve/pkg/proc/disasm.go
  35. 31
    25
      vendor/github.com/derekparker/delve/pkg/proc/disasm_amd64.go
  36. 0
    0
      vendor/github.com/derekparker/delve/pkg/proc/doc.go
  37. 454
    98
      vendor/github.com/derekparker/delve/pkg/proc/eval.go
  38. 561
    0
      vendor/github.com/derekparker/delve/pkg/proc/fncall.go
  39. 1877
    0
      vendor/github.com/derekparker/delve/pkg/proc/gdbserial/gdbserver.go
  40. 1233
    0
      vendor/github.com/derekparker/delve/pkg/proc/gdbserial/gdbserver_conn.go
  41. 16
    0
      vendor/github.com/derekparker/delve/pkg/proc/gdbserial/gdbserver_unix.go
  42. 10
    0
      vendor/github.com/derekparker/delve/pkg/proc/gdbserial/gdbserver_windows.go
  43. 267
    0
      vendor/github.com/derekparker/delve/pkg/proc/gdbserial/rr.go
  44. 129
    0
      vendor/github.com/derekparker/delve/pkg/proc/interface.go
  45. 39
    0
      vendor/github.com/derekparker/delve/pkg/proc/linutil/auxv.go
  46. 4
    0
      vendor/github.com/derekparker/delve/pkg/proc/linutil/doc.go
  47. 156
    0
      vendor/github.com/derekparker/delve/pkg/proc/mem.go
  48. 48
    34
      vendor/github.com/derekparker/delve/pkg/proc/moduledata.go
  49. 0
    0
      vendor/github.com/derekparker/delve/pkg/proc/native/exc.h
  50. 2
    0
      vendor/github.com/derekparker/delve/pkg/proc/native/exc_user_darwin.c
  51. 2
    0
      vendor/github.com/derekparker/delve/pkg/proc/native/exec_darwin.c
  52. 2
    0
      vendor/github.com/derekparker/delve/pkg/proc/native/exec_darwin.h
  53. 0
    0
      vendor/github.com/derekparker/delve/pkg/proc/native/mach_exc.defs
  54. 0
    0
      vendor/github.com/derekparker/delve/pkg/proc/native/mach_exc.h
  55. 2
    0
      vendor/github.com/derekparker/delve/pkg/proc/native/mach_exc_user_darwin.c
  56. 128
    0
      vendor/github.com/derekparker/delve/pkg/proc/native/nonative_darwin.go
  57. 453
    0
      vendor/github.com/derekparker/delve/pkg/proc/native/proc.go
  58. 2
    0
      vendor/github.com/derekparker/delve/pkg/proc/native/proc_darwin.c
  59. 118
    159
      vendor/github.com/derekparker/delve/pkg/proc/native/proc_darwin.go
  60. 2
    0
      vendor/github.com/derekparker/delve/pkg/proc/native/proc_darwin.h
  61. 176
    165
      vendor/github.com/derekparker/delve/pkg/proc/native/proc_linux.go
  62. 497
    0
      vendor/github.com/derekparker/delve/pkg/proc/native/proc_windows.go
  63. 3
    1
      vendor/github.com/derekparker/delve/pkg/proc/native/ptrace_darwin.go
  64. 13
    26
      vendor/github.com/derekparker/delve/pkg/proc/native/ptrace_linux.go
  65. 46
    34
      vendor/github.com/derekparker/delve/pkg/proc/native/registers_darwin_amd64.go
  66. 77
    60
      vendor/github.com/derekparker/delve/pkg/proc/native/registers_linux_amd64.go
  67. 69
    26
      vendor/github.com/derekparker/delve/pkg/proc/native/registers_windows_amd64.go
  68. 1
    1
      vendor/github.com/derekparker/delve/pkg/proc/native/syscall_windows.go
  69. 1
    1
      vendor/github.com/derekparker/delve/pkg/proc/native/syscall_windows_amd64.go
  70. 174
    0
      vendor/github.com/derekparker/delve/pkg/proc/native/threads.go
  71. 2
    0
      vendor/github.com/derekparker/delve/pkg/proc/native/threads_darwin.c
  72. 37
    20
      vendor/github.com/derekparker/delve/pkg/proc/native/threads_darwin.go
  73. 2
    0
      vendor/github.com/derekparker/delve/pkg/proc/native/threads_darwin.h
  74. 132
    0
      vendor/github.com/derekparker/delve/pkg/proc/native/threads_linux.go
  75. 38
    31
      vendor/github.com/derekparker/delve/pkg/proc/native/threads_windows.go
  76. 1
    1
      vendor/github.com/derekparker/delve/pkg/proc/native/zsyscall_windows.go
  77. 658
    0
      vendor/github.com/derekparker/delve/pkg/proc/proc.go
  78. 348
    0
      vendor/github.com/derekparker/delve/pkg/proc/registers.go
  79. 90
    0
      vendor/github.com/derekparker/delve/pkg/proc/registers_amd64.go
  80. 687
    0
      vendor/github.com/derekparker/delve/pkg/proc/stack.go
  81. 568
    0
      vendor/github.com/derekparker/delve/pkg/proc/threads.go
  82. 1288
    0
      vendor/github.com/derekparker/delve/pkg/proc/types.go
  83. 2119
    0
      vendor/github.com/derekparker/delve/pkg/proc/variables.go
  84. 721
    178
      vendor/github.com/derekparker/delve/pkg/terminal/command.go
  85. 191
    0
      vendor/github.com/derekparker/delve/pkg/terminal/config.go
  86. 3
    2
      vendor/github.com/derekparker/delve/pkg/terminal/disasmprint.go
  87. 7
    7
      vendor/github.com/derekparker/delve/pkg/terminal/docgen.go
  88. 175
    31
      vendor/github.com/derekparker/delve/pkg/terminal/terminal.go
  89. 0
    0
      vendor/github.com/derekparker/delve/pkg/terminal/terminal_other.go
  90. 0
    0
      vendor/github.com/derekparker/delve/pkg/terminal/terminal_windows.go
  91. 4
    1
      vendor/github.com/derekparker/delve/pkg/version/version.go
  92. 0
    79
      vendor/github.com/derekparker/delve/proc/arch.go
  93. 0
    163
      vendor/github.com/derekparker/delve/proc/breakpoints.go
  94. 0
    67
      vendor/github.com/derekparker/delve/proc/disasm.go
  95. 0
    113
      vendor/github.com/derekparker/delve/proc/go_version.go
  96. 0
    57
      vendor/github.com/derekparker/delve/proc/mem.go
  97. 0
    942
      vendor/github.com/derekparker/delve/proc/proc.go
  98. 0
    643
      vendor/github.com/derekparker/delve/proc/proc_windows.go
  99. 0
    13
      vendor/github.com/derekparker/delve/proc/ptrace_windows.go
  100. 0
    0
      vendor/github.com/derekparker/delve/proc/registers.go

+ 24
- 0
vendor/github.com/cosiner/argv/LICENSE View File

@@ -0,0 +1,24 @@
1
+The MIT License (MIT)
2
+
3
+Copyright (c) 2017 aihui zhu
4
+
5
+Permission is hereby granted, free of charge, to any person
6
+obtaining a copy of this software and associated documentation
7
+files (the "Software"), to deal in the Software without
8
+restriction, including without limitation the rights to use,
9
+copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+copies of the Software, and to permit persons to whom the
11
+Software is furnished to do so, subject to the following
12
+conditions:
13
+
14
+The above copyright notice and this permission notice shall be
15
+included in all copies or substantial portions of the Software.
16
+
17
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24
+OTHER DEALINGS IN THE SOFTWARE.

+ 34
- 0
vendor/github.com/cosiner/argv/argv.go View File

@@ -0,0 +1,34 @@
1
+// Package argv parse command line string into arguments array using the bash syntax.
2
+package argv
3
+
4
+import "strings"
5
+
6
+// ParseEnv parsing environment variables as key/value pair.
7
+//
8
+// Item will be ignored if one of the key and value is empty.
9
+func ParseEnv(env []string) map[string]string {
10
+	var m map[string]string
11
+	for _, e := range env {
12
+		secs := strings.SplitN(e, "=", 2)
13
+		if len(secs) == 2 {
14
+			key := strings.TrimSpace(secs[0])
15
+			val := strings.TrimSpace(secs[1])
16
+			if key == "" || val == "" {
17
+				continue
18
+			}
19
+			if m == nil {
20
+				m = make(map[string]string)
21
+			}
22
+			m[key] = val
23
+		}
24
+	}
25
+	return m
26
+}
27
+
28
+// Argv split cmdline string as array of argument array by the '|' character.
29
+//
30
+// The parsing rules is same as bash. The environment variable will be replaced
31
+// and string surround by '`' will be passed to reverse quote parser.
32
+func Argv(cmdline []rune, env map[string]string, reverseQuoteParser ReverseQuoteParser) ([][]string, error) {
33
+	return NewParser(NewScanner(cmdline, env), reverseQuoteParser).Parse()
34
+}

+ 79
- 0
vendor/github.com/cosiner/argv/cmd.go View File

@@ -0,0 +1,79 @@
1
+package argv
2
+
3
+import (
4
+	"bytes"
5
+	"errors"
6
+	"io"
7
+	"os/exec"
8
+	"strings"
9
+)
10
+
11
+// Run execute cmdline string and return the output
12
+func Run(cmdline []rune, env map[string]string) ([]rune, error) {
13
+	args, err := Argv(cmdline, env, Run)
14
+	if err != nil {
15
+		return nil, err
16
+	}
17
+	cmds, err := Cmds(args)
18
+	if err != nil {
19
+		return nil, err
20
+	}
21
+
22
+	output := bytes.NewBuffer(make([]byte, 0, 1024))
23
+	err = Pipe(nil, output, cmds...)
24
+	str := output.String()
25
+	str = strings.TrimSpace(str)
26
+	return []rune(str), err
27
+}
28
+
29
+// Cmds generate exec.Cmd for each command.
30
+func Cmds(args [][]string) ([]*exec.Cmd, error) {
31
+	var cmds []*exec.Cmd
32
+	for _, argv := range args {
33
+		if len(argv) == 0 {
34
+			return nil, errors.New("invalid cmd")
35
+		}
36
+
37
+		cmds = append(cmds, exec.Command(argv[0], argv[1:]...))
38
+	}
39
+	return cmds, nil
40
+}
41
+
42
+// Pipe pipe previous command's stdout to next command's stdin, if in or
43
+// out is nil, it will be ignored.
44
+func Pipe(in io.Reader, out io.Writer, cmds ...*exec.Cmd) error {
45
+	l := len(cmds)
46
+	if l == 0 {
47
+		return nil
48
+	}
49
+
50
+	var err error
51
+	for i := 1; i < l; i++ {
52
+		cmds[i].Stdin, err = cmds[i-1].StdoutPipe()
53
+		if err != nil {
54
+			break
55
+		}
56
+	}
57
+	if err != nil {
58
+		return err
59
+	}
60
+	if in != nil {
61
+		cmds[0].Stdin = in
62
+	}
63
+	if out != nil {
64
+		cmds[l-1].Stdout = out
65
+	}
66
+	for i := range cmds {
67
+		err = cmds[i].Start()
68
+		if err != nil {
69
+			return err
70
+		}
71
+	}
72
+	for i := range cmds {
73
+		err = cmds[i].Wait()
74
+		if err != nil {
75
+			return err
76
+		}
77
+	}
78
+	return nil
79
+}

+ 222
- 0
vendor/github.com/cosiner/argv/parser.go View File

@@ -0,0 +1,222 @@
1
+package argv
2
+
3
+import "errors"
4
+
5
+type (
6
+	// ReverseQuoteParser parse strings quoted by '`' and return it's result. Commonly,
7
+	// it should run it os command.
8
+	ReverseQuoteParser func([]rune, map[string]string) ([]rune, error)
9
+
10
+	// Parser take tokens from Scanner, and do syntax checking, and generate the splitted arguments array.
11
+	Parser struct {
12
+		s      *Scanner
13
+		tokbuf []Token
14
+		r      ReverseQuoteParser
15
+
16
+		sections    [][]string
17
+		currSection []string
18
+
19
+		currStrValid bool
20
+		currStr      []rune
21
+	}
22
+)
23
+
24
+// NewParser create a cmdline string parser.
25
+func NewParser(s *Scanner, r ReverseQuoteParser) *Parser {
26
+	if r == nil {
27
+		r = func(r []rune, env map[string]string) ([]rune, error) {
28
+			return r, nil
29
+		}
30
+	}
31
+
32
+	return &Parser{
33
+		s: s,
34
+		r: r,
35
+	}
36
+}
37
+
38
+func (p *Parser) nextToken() (Token, error) {
39
+	if l := len(p.tokbuf); l > 0 {
40
+		tok := p.tokbuf[l-1]
41
+		p.tokbuf = p.tokbuf[:l-1]
42
+		return tok, nil
43
+	}
44
+
45
+	return p.s.Next()
46
+}
47
+
48
+var (
49
+	// ErrInvalidSyntax was reported if there is a syntax error in command line string.
50
+	ErrInvalidSyntax = errors.New("invalid syntax")
51
+)
52
+
53
+func (p *Parser) unreadToken(tok Token) {
54
+	p.tokbuf = append(p.tokbuf, tok)
55
+}
56
+
57
+// Parse split command line string into arguments array.
58
+//
59
+// EBNF:
60
+//   Cmdline = Section [ Pipe Cmdline ]
61
+//   Section = [Space] SpacedSection { SpacedSection }
62
+//   SpacedSection = MultipleUnit [Space]
63
+//   MultipleUnit = Unit {Unit}
64
+//   Unit = String | ReverseQuote
65
+func (p *Parser) Parse() ([][]string, error) {
66
+	err := p.cmdline()
67
+	if err != nil {
68
+		return nil, err
69
+	}
70
+	return p.sections, nil
71
+}
72
+
73
+func (p *Parser) cmdline() error {
74
+	err := p.section()
75
+	if err != nil {
76
+		return err
77
+	}
78
+	p.endSection()
79
+
80
+	tok, err := p.nextToken()
81
+	if err != nil {
82
+		return err
83
+	}
84
+	if tok.Type == TokEOF {
85
+		return nil
86
+	}
87
+	if !p.accept(tok.Type, TokPipe) {
88
+		return ErrInvalidSyntax
89
+	}
90
+	return p.cmdline()
91
+}
92
+
93
+func (p *Parser) section() error {
94
+	leftSpace, err := p.optional(TokSpace)
95
+	if err != nil {
96
+		return err
97
+	}
98
+
99
+	var isFirst = true
100
+	for {
101
+		unit, err := p.spacedSection()
102
+		if isFirst {
103
+			isFirst = false
104
+		} else {
105
+			if err == ErrInvalidSyntax {
106
+				break
107
+			}
108
+		}
109
+		if err != nil {
110
+			return err
111
+		}
112
+
113
+		p.appendUnit(leftSpace, unit)
114
+		leftSpace = unit.rightSpace
115
+	}
116
+	return nil
117
+}
118
+
119
+type unit struct {
120
+	rightSpace bool
121
+	toks       []Token
122
+}
123
+
124
+func (p *Parser) spacedSection() (u unit, err error) {
125
+	u.toks, err = p.multipleUnit()
126
+	if err != nil {
127
+		return
128
+	}
129
+	u.rightSpace, err = p.optional(TokSpace)
130
+	return
131
+}
132
+
133
+func (p *Parser) multipleUnit() ([]Token, error) {
134
+	var (
135
+		toks    []Token
136
+		isFirst = true
137
+	)
138
+	for {
139
+		tok, err := p.unit()
140
+		if isFirst {
141
+			isFirst = false
142
+		} else {
143
+			if err == ErrInvalidSyntax {
144
+				break
145
+			}
146
+		}
147
+		if err != nil {
148
+			return nil, err
149
+		}
150
+		toks = append(toks, tok)
151
+	}
152
+	return toks, nil
153
+}
154
+
155
+func (p *Parser) unit() (Token, error) {
156
+	tok, err := p.nextToken()
157
+	if err != nil {
158
+		return tok, err
159
+	}
160
+	if p.accept(tok.Type, TokString, TokReversequote) {
161
+		return tok, nil
162
+	}
163
+	p.unreadToken(tok)
164
+	return tok, ErrInvalidSyntax
165
+}
166
+
167
+func (p *Parser) optional(typ TokenType) (bool, error) {
168
+	tok, err := p.nextToken()
169
+	if err != nil {
170
+		return false, err
171
+	}
172
+	var ok bool
173
+	if ok = p.accept(tok.Type, typ); !ok {
174
+		p.unreadToken(tok)
175
+	}
176
+	return ok, nil
177
+}
178
+
179
+func (p *Parser) accept(t TokenType, types ...TokenType) bool {
180
+	for _, typ := range types {
181
+		if t == typ {
182
+			return true
183
+		}
184
+	}
185
+	return false
186
+}
187
+
188
+func (p *Parser) appendUnit(leftSpace bool, u unit) error {
189
+	if leftSpace {
190
+		p.currStr = p.currStr[:0]
191
+	}
192
+	for _, tok := range u.toks {
193
+		if tok.Type == TokReversequote {
194
+			val, err := p.r(tok.Value, p.s.envs())
195
+			if err != nil {
196
+				return err
197
+			}
198
+			p.currStr = append(p.currStr, val...)
199
+		} else {
200
+			p.currStr = append(p.currStr, tok.Value...)
201
+		}
202
+	}
203
+	p.currStrValid = true
204
+	if u.rightSpace {
205
+		p.currSection = append(p.currSection, string(p.currStr))
206
+		p.currStr = p.currStr[:0]
207
+		p.currStrValid = false
208
+	}
209
+	return nil
210
+}
211
+
212
+func (p *Parser) endSection() {
213
+	if p.currStrValid {
214
+		p.currSection = append(p.currSection, string(p.currStr))
215
+	}
216
+	p.currStr = p.currStr[:0]
217
+	p.currStrValid = false
218
+	if len(p.currSection) > 0 {
219
+		p.sections = append(p.sections, p.currSection)
220
+		p.currSection = nil
221
+	}
222
+}

+ 282
- 0
vendor/github.com/cosiner/argv/scanner.go View File

@@ -0,0 +1,282 @@
1
+package argv
2
+
3
+import "unicode"
4
+
5
+// Scanner is a cmdline string scanner.
6
+//
7
+// It split cmdline string to tokens: space, string, pipe, reverse quote string.
8
+type Scanner struct {
9
+	env map[string]string
10
+
11
+	text      []rune
12
+	rpos      int
13
+	dollarBuf []rune
14
+}
15
+
16
+// NewScanner create a scanner and init it's internal states.
17
+func NewScanner(text []rune, env map[string]string) *Scanner {
18
+	return &Scanner{
19
+		text: text,
20
+		env:  env,
21
+	}
22
+}
23
+
24
+func (s *Scanner) envs() map[string]string {
25
+	return s.env
26
+}
27
+
28
+const _RuneEOF = 0
29
+
30
+func (s *Scanner) nextRune() rune {
31
+	if s.rpos >= len(s.text) {
32
+		return _RuneEOF
33
+	}
34
+
35
+	r := s.text[s.rpos]
36
+	s.rpos++
37
+	return r
38
+}
39
+
40
+func (s *Scanner) unreadRune(r rune) {
41
+	if r != _RuneEOF {
42
+		s.rpos--
43
+	}
44
+}
45
+
46
+func (s *Scanner) isEscapeChars(r rune) (rune, bool) {
47
+	switch r {
48
+	case 'a':
49
+		return '\a', true
50
+	case 'b':
51
+		return '\b', true
52
+	case 'f':
53
+		return '\f', true
54
+	case 'n':
55
+		return '\n', true
56
+	case 'r':
57
+		return '\r', true
58
+	case 't':
59
+		return '\t', true
60
+	case 'v':
61
+		return '\v', true
62
+	case '\\':
63
+		return '\\', true
64
+	case '$':
65
+		return '$', true
66
+	}
67
+	return r, false
68
+}
69
+
70
+func (s *Scanner) endEnv(r rune) bool {
71
+	if r == '_' || (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9') {
72
+		return false
73
+	}
74
+	return true
75
+}
76
+
77
+// TokenType is the type of tokens recognized by the scanner.
78
+type TokenType uint32
79
+
80
+// Token is generated by the scanner with a type and value.
81
+type Token struct {
82
+	Type  TokenType
83
+	Value []rune
84
+}
85
+
86
+const (
87
+	// TokString for string, single quoted string and double quoted string
88
+	TokString TokenType = iota + 1
89
+	// TokPipe is the '|' character
90
+	TokPipe
91
+	// TokReversequote is reverse quoted string
92
+	TokReversequote
93
+	// TokSpace represent space character sequence
94
+	TokSpace
95
+	// TokEOF means the input end.
96
+	TokEOF
97
+)
98
+
99
+func (s *Scanner) getEnv(name string) string {
100
+	return s.env[name]
101
+}
102
+
103
+func (s *Scanner) specialVar(r rune) (string, bool) {
104
+	switch r {
105
+	case '0', '*', '#', '@', '?', '$':
106
+		v, has := s.env[string(r)]
107
+		return v, has
108
+	default:
109
+		return "", false
110
+	}
111
+}
112
+
113
+func (s *Scanner) checkDollarStart(tok *Token, r rune, from, switchTo uint8) uint8 {
114
+	state := from
115
+	nr := s.nextRune()
116
+	if val, has := s.specialVar(nr); has {
117
+		if val != "" {
118
+			tok.Value = append(tok.Value, []rune(val)...)
119
+		}
120
+	} else if s.endEnv(nr) {
121
+		tok.Value = append(tok.Value, r)
122
+		s.unreadRune(nr)
123
+	} else {
124
+		state = switchTo
125
+		s.dollarBuf = append(s.dollarBuf[:0], nr)
126
+	}
127
+	return state
128
+}
129
+
130
+func (s *Scanner) checkDollarEnd(tok *Token, r rune, from, switchTo uint8) uint8 {
131
+	var state = from
132
+	if s.endEnv(r) {
133
+		tok.Value = append(tok.Value, []rune(s.getEnv(string(s.dollarBuf)))...)
134
+		state = switchTo
135
+		s.unreadRune(r)
136
+	} else {
137
+		s.dollarBuf = append(s.dollarBuf, r)
138
+	}
139
+	return state
140
+}
141
+
142
+// Next return next token, if it reach the end, TOK_EOF will be returned.
143
+//
144
+// Error is returned for invalid syntax such as unpaired quotes.
145
+func (s *Scanner) Next() (Token, error) {
146
+	const (
147
+		Initial = iota + 1
148
+		Space
149
+		ReverseQuote
150
+		String
151
+		StringDollar
152
+		StringQuoteSingle
153
+		StringQuoteDouble
154
+		StringQuoteDoubleDollar
155
+	)
156
+
157
+	var (
158
+		tok Token
159
+
160
+		state uint8 = Initial
161
+	)
162
+	s.dollarBuf = s.dollarBuf[:0]
163
+	for {
164
+		r := s.nextRune()
165
+		switch state {
166
+		case Initial:
167
+			switch {
168
+			case r == _RuneEOF:
169
+				tok.Type = TokEOF
170
+				return tok, nil
171
+			case r == '|':
172
+				tok.Type = TokPipe
173
+				return tok, nil
174
+			case r == '`':
175
+				state = ReverseQuote
176
+			case unicode.IsSpace(r):
177
+				state = Space
178
+				s.unreadRune(r)
179
+			default:
180
+				state = String
181
+				s.unreadRune(r)
182
+			}
183
+		case Space:
184
+			if r == _RuneEOF || !unicode.IsSpace(r) {
185
+				s.unreadRune(r)
186
+				tok.Type = TokSpace
187
+				return tok, nil
188
+			}
189
+		case ReverseQuote:
190
+			switch r {
191
+			case _RuneEOF:
192
+				return tok, ErrInvalidSyntax
193
+			case '`':
194
+				tok.Type = TokReversequote
195
+				return tok, nil
196
+			default:
197
+				tok.Value = append(tok.Value, r)
198
+			}
199
+		case String:
200
+			switch {
201
+			case r == _RuneEOF || r == '|' || r == '`' || unicode.IsSpace(r):
202
+				tok.Type = TokString
203
+				s.unreadRune(r)
204
+				return tok, nil
205
+			case r == '\'':
206
+				state = StringQuoteSingle
207
+			case r == '"':
208
+				state = StringQuoteDouble
209
+			case r == '\\':
210
+				nr := s.nextRune()
211
+				if nr == _RuneEOF {
212
+					return tok, ErrInvalidSyntax
213
+				}
214
+				tok.Value = append(tok.Value, nr)
215
+			case r == '$':
216
+				state = s.checkDollarStart(&tok, r, state, StringDollar)
217
+			default:
218
+				tok.Value = append(tok.Value, r)
219
+			}
220
+		case StringDollar:
221
+			state = s.checkDollarEnd(&tok, r, state, String)
222
+		case StringQuoteSingle:
223
+			switch r {
224
+			case _RuneEOF:
225
+				return tok, ErrInvalidSyntax
226
+			case '\'':
227
+				state = String
228
+			case '\\':
229
+				nr := s.nextRune()
230
+				if escape, ok := s.isEscapeChars(nr); ok {
231
+					tok.Value = append(tok.Value, escape)
232
+				} else {
233
+					tok.Value = append(tok.Value, r)
234
+					s.unreadRune(nr)
235
+				}
236
+			default:
237
+				tok.Value = append(tok.Value, r)
238
+			}
239
+		case StringQuoteDouble:
240
+			switch r {
241
+			case _RuneEOF:
242
+				return tok, ErrInvalidSyntax
243
+			case '"':
244
+				state = String
245
+			case '\\':
246
+				nr := s.nextRune()
247
+				if nr == _RuneEOF {
248
+					return tok, ErrInvalidSyntax
249
+				}
250
+				if escape, ok := s.isEscapeChars(nr); ok {
251
+					tok.Value = append(tok.Value, escape)
252
+				} else {
253
+					tok.Value = append(tok.Value, r)
254
+					s.unreadRune(nr)
255
+				}
256
+			case '$':
257
+				state = s.checkDollarStart(&tok, r, state, StringQuoteDoubleDollar)
258
+			default:
259
+				tok.Value = append(tok.Value, r)
260
+			}
261
+		case StringQuoteDoubleDollar:
262
+			state = s.checkDollarEnd(&tok, r, state, StringQuoteDouble)
263
+		}
264
+	}
265
+}
266
+
267
+// Scan is a utility function help split input text as tokens.
268
+func Scan(text []rune, env map[string]string) ([]Token, error) {
269
+	s := NewScanner(text, env)
270
+	var tokens []Token
271
+	for {
272
+		tok, err := s.Next()
273
+		if err != nil {
274
+			return nil, err
275
+		}
276
+		tokens = append(tokens, tok)
277
+		if tok.Type == TokEOF {
278
+			break
279
+		}
280
+	}
281
+	return tokens, nil
282
+}

+ 0
- 122
vendor/github.com/derekparker/delve/dwarf/line/line_parser.go View File

@@ -1,122 +0,0 @@
1
-package line
2
-
3
-import (
4
-	"bytes"
5
-	"encoding/binary"
6
-
7
-	"github.com/derekparker/delve/dwarf/util"
8
-)
9
-
10
-type DebugLinePrologue struct {
11
-	UnitLength     uint32
12
-	Version        uint16
13
-	Length         uint32
14
-	MinInstrLength uint8
15
-	InitialIsStmt  uint8
16
-	LineBase       int8
17
-	LineRange      uint8
18
-	OpcodeBase     uint8
19
-	StdOpLengths   []uint8
20
-}
21
-
22
-type DebugLineInfo struct {
23
-	Prologue     *DebugLinePrologue
24
-	IncludeDirs  []string
25
-	FileNames    []*FileEntry
26
-	Instructions []byte
27
-	Lookup       map[string]*FileEntry
28
-}
29
-
30
-type FileEntry struct {
31
-	Name        string
32
-	DirIdx      uint64
33
-	LastModTime uint64
34
-	Length      uint64
35
-}
36
-
37
-type DebugLines []*DebugLineInfo
38
-
39
-func (d *DebugLines) GetLineInfo(name string) *DebugLineInfo {
40
-	// Find in which table file exists and return it.
41
-	for _, l := range *d {
42
-		if _, ok := l.Lookup[name]; ok {
43
-			return l
44
-		}
45
-	}
46
-	return nil
47
-}
48
-
49
-func Parse(data []byte) DebugLines {
50
-	var (
51
-		lines = make(DebugLines, 0)
52
-		buf   = bytes.NewBuffer(data)
53
-	)
54
-
55
-	// We have to parse multiple file name tables here.
56
-	for buf.Len() > 0 {
57
-		dbl := new(DebugLineInfo)
58
-		dbl.Lookup = make(map[string]*FileEntry)
59
-
60
-		parseDebugLinePrologue(dbl, buf)
61
-		parseIncludeDirs(dbl, buf)
62
-		parseFileEntries(dbl, buf)
63
-
64
-		// Instructions size calculation breakdown:
65
-		//   - dbl.Prologue.UnitLength is the length of the entire unit, not including the 4 bytes to represent that length.
66
-		//   - dbl.Prologue.Length is the length of the prologue not including unit length, version or prologue length itself.
67
-		//   - So you have UnitLength - PrologueLength - (version_length_bytes(2) + prologue_length_bytes(4)).
68
-		dbl.Instructions = buf.Next(int(dbl.Prologue.UnitLength - dbl.Prologue.Length - 6))
69
-
70
-		lines = append(lines, dbl)
71
-	}
72
-
73
-	return lines
74
-}
75
-
76
-func parseDebugLinePrologue(dbl *DebugLineInfo, buf *bytes.Buffer) {
77
-	p := new(DebugLinePrologue)
78
-
79
-	p.UnitLength = binary.LittleEndian.Uint32(buf.Next(4))
80
-	p.Version = binary.LittleEndian.Uint16(buf.Next(2))
81
-	p.Length = binary.LittleEndian.Uint32(buf.Next(4))
82
-	p.MinInstrLength = uint8(buf.Next(1)[0])
83
-	p.InitialIsStmt = uint8(buf.Next(1)[0])
84
-	p.LineBase = int8(buf.Next(1)[0])
85
-	p.LineRange = uint8(buf.Next(1)[0])
86
-	p.OpcodeBase = uint8(buf.Next(1)[0])
87
-
88
-	p.StdOpLengths = make([]uint8, p.OpcodeBase-1)
89
-	binary.Read(buf, binary.LittleEndian, &p.StdOpLengths)
90
-
91
-	dbl.Prologue = p
92
-}
93
-
94
-func parseIncludeDirs(info *DebugLineInfo, buf *bytes.Buffer) {
95
-	for {
96
-		str, _ := util.ParseString(buf)
97
-		if str == "" {
98
-			break
99
-		}
100
-
101
-		info.IncludeDirs = append(info.IncludeDirs, str)
102
-	}
103
-}
104
-
105
-func parseFileEntries(info *DebugLineInfo, buf *bytes.Buffer) {
106
-	for {
107
-		entry := new(FileEntry)
108
-
109
-		name, _ := util.ParseString(buf)
110
-		if name == "" {
111
-			break
112
-		}
113
-
114
-		entry.Name = name
115
-		entry.DirIdx, _ = util.DecodeULEB128(buf)
116
-		entry.LastModTime, _ = util.DecodeULEB128(buf)
117
-		entry.Length, _ = util.DecodeULEB128(buf)
118
-
119
-		info.FileNames = append(info.FileNames, entry)
120
-		info.Lookup[name] = entry
121
-	}
122
-}

+ 0
- 252
vendor/github.com/derekparker/delve/dwarf/line/state_machine.go View File

@@ -1,252 +0,0 @@
1
-package line
2
-
3
-import (
4
-	"bytes"
5
-	"encoding/binary"
6
-	"errors"
7
-	"fmt"
8
-
9
-	"github.com/derekparker/delve/dwarf/util"
10
-)
11
-
12
-type Location struct {
13
-	File    string
14
-	Line    int
15
-	Address uint64
16
-	Delta   int
17
-}
18
-
19
-type StateMachine struct {
20
-	dbl             *DebugLineInfo
21
-	file            string
22
-	line            int
23
-	address         uint64
24
-	column          uint
25
-	isStmt          bool
26
-	basicBlock      bool
27
-	endSeq          bool
28
-	lastWasStandard bool
29
-	lastDelta       int
30
-}
31
-
32
-type opcodefn func(*StateMachine, *bytes.Buffer)
33
-
34
-// Special opcodes
35
-const (
36
-	DW_LNS_copy             = 1
37
-	DW_LNS_advance_pc       = 2
38
-	DW_LNS_advance_line     = 3
39
-	DW_LNS_set_file         = 4
40
-	DW_LNS_set_column       = 5
41
-	DW_LNS_negate_stmt      = 6
42
-	DW_LNS_set_basic_block  = 7
43
-	DW_LNS_const_add_pc     = 8
44
-	DW_LNS_fixed_advance_pc = 9
45
-)
46
-
47
-// Extended opcodes
48
-const (
49
-	DW_LINE_end_sequence = 1
50
-	DW_LINE_set_address  = 2
51
-	DW_LINE_define_file  = 3
52
-)
53
-
54
-var standardopcodes = map[byte]opcodefn{
55
-	DW_LNS_copy:             copyfn,
56
-	DW_LNS_advance_pc:       advancepc,
57
-	DW_LNS_advance_line:     advanceline,
58
-	DW_LNS_set_file:         setfile,
59
-	DW_LNS_set_column:       setcolumn,
60
-	DW_LNS_negate_stmt:      negatestmt,
61
-	DW_LNS_set_basic_block:  setbasicblock,
62
-	DW_LNS_const_add_pc:     constaddpc,
63
-	DW_LNS_fixed_advance_pc: fixedadvancepc,
64
-}
65
-
66
-var extendedopcodes = map[byte]opcodefn{
67
-	DW_LINE_end_sequence: endsequence,
68
-	DW_LINE_set_address:  setaddress,
69
-	DW_LINE_define_file:  definefile,
70
-}
71
-
72
-func newStateMachine(dbl *DebugLineInfo) *StateMachine {
73
-	return &StateMachine{dbl: dbl, file: dbl.FileNames[0].Name, line: 1}
74
-}
75
-
76
-// Returns all PCs for a given file/line. Useful for loops where the 'for' line
77
-// could be split amongst 2 PCs.
78
-func (dbl *DebugLines) AllPCsForFileLine(f string, l int) (pcs []uint64) {
79
-	var (
80
-		foundFile bool
81
-		lastAddr  uint64
82
-		lineInfo  = dbl.GetLineInfo(f)
83
-		sm        = newStateMachine(lineInfo)
84
-		buf       = bytes.NewBuffer(lineInfo.Instructions)
85
-	)
86
-
87
-	for b, err := buf.ReadByte(); err == nil; b, err = buf.ReadByte() {
88
-		findAndExecOpcode(sm, buf, b)
89
-		if foundFile && sm.file != f {
90
-			return
91
-		}
92
-		if sm.line == l && sm.file == f && sm.address != lastAddr {
93
-			foundFile = true
94
-			pcs = append(pcs, sm.address)
95
-			line := sm.line
96
-			// Keep going until we're on a different line. We only care about
97
-			// when a line comes back around (i.e. for loop) so get to next line,
98
-			// and try to find the line we care about again.
99
-			for b, err := buf.ReadByte(); err == nil; b, err = buf.ReadByte() {
100
-				findAndExecOpcode(sm, buf, b)
101
-				if line < sm.line {
102
-					break
103
-				}
104
-			}
105
-		}
106
-	}
107
-	return
108
-}
109
-
110
-var NoSourceError = errors.New("no source available")
111
-
112
-func (dbl *DebugLines) AllPCsBetween(begin, end uint64, filename string) ([]uint64, error) {
113
-	lineInfo := dbl.GetLineInfo(filename)
114
-	if lineInfo == nil {
115
-		return nil, NoSourceError
116
-	}
117
-	var (
118
-		pcs      []uint64
119
-		lastaddr uint64
120
-		sm       = newStateMachine(lineInfo)
121
-		buf      = bytes.NewBuffer(lineInfo.Instructions)
122
-	)
123
-
124
-	for b, err := buf.ReadByte(); err == nil; b, err = buf.ReadByte() {
125
-		findAndExecOpcode(sm, buf, b)
126
-		if sm.address > end {
127
-			break
128
-		}
129
-		if sm.address >= begin && sm.address > lastaddr {
130
-			lastaddr = sm.address
131
-			pcs = append(pcs, sm.address)
132
-		}
133
-	}
134
-	return pcs, nil
135
-}
136
-
137
-func findAndExecOpcode(sm *StateMachine, buf *bytes.Buffer, b byte) {
138
-	switch {
139
-	case b == 0:
140
-		execExtendedOpcode(sm, b, buf)
141
-	case b < sm.dbl.Prologue.OpcodeBase:
142
-		execStandardOpcode(sm, b, buf)
143
-	default:
144
-		execSpecialOpcode(sm, b)
145
-	}
146
-}
147
-
148
-func execSpecialOpcode(sm *StateMachine, instr byte) {
149
-	var (
150
-		opcode  = uint8(instr)
151
-		decoded = opcode - sm.dbl.Prologue.OpcodeBase
152
-	)
153
-
154
-	if sm.dbl.Prologue.InitialIsStmt == uint8(1) {
155
-		sm.isStmt = true
156
-	}
157
-
158
-	sm.lastDelta = int(sm.dbl.Prologue.LineBase + int8(decoded%sm.dbl.Prologue.LineRange))
159
-	sm.line += sm.lastDelta
160
-	sm.address += uint64(decoded / sm.dbl.Prologue.LineRange)
161
-	sm.basicBlock = false
162
-	sm.lastWasStandard = false
163
-}
164
-
165
-func execExtendedOpcode(sm *StateMachine, instr byte, buf *bytes.Buffer) {
166
-	_, _ = util.DecodeULEB128(buf)
167
-	b, _ := buf.ReadByte()
168
-	fn, ok := extendedopcodes[b]
169
-	if !ok {
170
-		panic(fmt.Sprintf("Encountered unknown extended opcode %#v\n", b))
171
-	}
172
-	sm.lastWasStandard = false
173
-
174
-	fn(sm, buf)
175
-}
176
-
177
-func execStandardOpcode(sm *StateMachine, instr byte, buf *bytes.Buffer) {
178
-	fn, ok := standardopcodes[instr]
179
-	if !ok {
180
-		panic(fmt.Sprintf("Encountered unknown standard opcode %#v\n", instr))
181
-	}
182
-	sm.lastWasStandard = true
183
-
184
-	fn(sm, buf)
185
-}
186
-
187
-func copyfn(sm *StateMachine, buf *bytes.Buffer) {
188
-	sm.basicBlock = false
189
-}
190
-
191
-func advancepc(sm *StateMachine, buf *bytes.Buffer) {
192
-	addr, _ := util.DecodeULEB128(buf)
193
-	sm.address += addr * uint64(sm.dbl.Prologue.MinInstrLength)
194
-}
195
-
196
-func advanceline(sm *StateMachine, buf *bytes.Buffer) {
197
-	line, _ := util.DecodeSLEB128(buf)
198
-	sm.line += int(line)
199
-	sm.lastDelta = int(line)
200
-}
201
-
202
-func setfile(sm *StateMachine, buf *bytes.Buffer) {
203
-	i, _ := util.DecodeULEB128(buf)
204
-	sm.file = sm.dbl.FileNames[i-1].Name
205
-}
206
-
207
-func setcolumn(sm *StateMachine, buf *bytes.Buffer) {
208
-	c, _ := util.DecodeULEB128(buf)
209
-	sm.column = uint(c)
210
-}
211
-
212
-func negatestmt(sm *StateMachine, buf *bytes.Buffer) {
213
-	sm.isStmt = !sm.isStmt
214
-}
215
-
216
-func setbasicblock(sm *StateMachine, buf *bytes.Buffer) {
217
-	sm.basicBlock = true
218
-}
219
-
220
-func constaddpc(sm *StateMachine, buf *bytes.Buffer) {
221
-	sm.address += (255 / uint64(sm.dbl.Prologue.LineRange))
222
-}
223
-
224
-func fixedadvancepc(sm *StateMachine, buf *bytes.Buffer) {
225
-	var operand uint16
226
-	binary.Read(buf, binary.LittleEndian, &operand)
227
-
228
-	sm.address += uint64(operand)
229
-}
230
-
231
-func endsequence(sm *StateMachine, buf *bytes.Buffer) {
232
-	sm.endSeq = true
233
-}
234
-
235
-func setaddress(sm *StateMachine, buf *bytes.Buffer) {
236
-	var addr uint64
237
-
238
-	binary.Read(buf, binary.LittleEndian, &addr)
239
-
240
-	sm.address = addr
241
-}
242
-
243
-func definefile(sm *StateMachine, buf *bytes.Buffer) {
244
-	var (
245
-		_, _ = util.ParseString(buf)
246
-		_, _ = util.DecodeULEB128(buf)
247
-		_, _ = util.DecodeULEB128(buf)
248
-		_, _ = util.DecodeULEB128(buf)
249
-	)
250
-
251
-	// Don't do anything here yet.
252
-}

+ 0
- 84
vendor/github.com/derekparker/delve/dwarf/op/op.go View File

@@ -1,84 +0,0 @@
1
-package op
2
-
3
-import (
4
-	"bytes"
5
-	"encoding/binary"
6
-	"errors"
7
-	"fmt"
8
-
9
-	"github.com/derekparker/delve/dwarf/util"
10
-)
11
-
12
-const (
13
-	DW_OP_addr           = 0x3
14
-	DW_OP_call_frame_cfa = 0x9c
15
-	DW_OP_plus           = 0x22
16
-	DW_OP_consts         = 0x11
17
-	DW_OP_plus_uconsts   = 0x23
18
-)
19
-
20
-type stackfn func(*bytes.Buffer, []int64, int64) ([]int64, error)
21
-
22
-var oplut = map[byte]stackfn{
23
-	DW_OP_call_frame_cfa: callframecfa,
24
-	DW_OP_plus:           plus,
25
-	DW_OP_consts:         consts,
26
-	DW_OP_addr:           addr,
27
-	DW_OP_plus_uconsts:   plusuconsts,
28
-}
29
-
30
-func ExecuteStackProgram(cfa int64, instructions []byte) (int64, error) {
31
-	stack := make([]int64, 0, 3)
32
-	buf := bytes.NewBuffer(instructions)
33
-
34
-	for opcode, err := buf.ReadByte(); err == nil; opcode, err = buf.ReadByte() {
35
-		fn, ok := oplut[opcode]
36
-		if !ok {
37
-			return 0, fmt.Errorf("invalid instruction %#v", opcode)
38
-		}
39
-
40
-		stack, err = fn(buf, stack, cfa)
41
-		if err != nil {
42
-			return 0, err
43
-		}
44
-	}
45
-
46
-	if len(stack) == 0 {
47
-		return 0, errors.New("empty OP stack")
48
-	}
49
-
50
-	return stack[len(stack)-1], nil
51
-}
52
-
53
-func callframecfa(buf *bytes.Buffer, stack []int64, cfa int64) ([]int64, error) {
54
-	if cfa == 0 {
55
-		return stack, fmt.Errorf("Could not retrieve CFA for current PC")
56
-	}
57
-	return append(stack, int64(cfa)), nil
58
-}
59
-
60
-func addr(buf *bytes.Buffer, stack []int64, cfa int64) ([]int64, error) {
61
-	return append(stack, int64(binary.LittleEndian.Uint64(buf.Next(8)))), nil
62
-}
63
-
64
-func plus(buf *bytes.Buffer, stack []int64, cfa int64) ([]int64, error) {
65
-	var (
66
-		slen   = len(stack)
67
-		digits = stack[slen-2 : slen]
68
-		st     = stack[:slen-2]
69
-	)
70
-
71
-	return append(st, digits[0]+digits[1]), nil
72
-}
73
-
74
-func plusuconsts(buf *bytes.Buffer, stack []int64, cfa int64) ([]int64, error) {
75
-	slen := len(stack)
76
-	num, _ := util.DecodeULEB128(buf)
77
-	stack[slen-1] = stack[slen-1] + int64(num)
78
-	return stack, nil
79
-}
80
-
81
-func consts(buf *bytes.Buffer, stack []int64, cfa int64) ([]int64, error) {
82
-	num, _ := util.DecodeSLEB128(buf)
83
-	return append(stack, num), nil
84
-}

vendor/github.com/derekparker/delve/config/config.go → vendor/github.com/derekparker/delve/pkg/config/config.go View File

@@ -7,7 +7,7 @@ import (
7 7
 	"os/user"
8 8
 	"path"
9 9
 
10
-	yaml "gopkg.in/yaml.v2"
10
+	"gopkg.in/yaml.v2"
11 11
 )
12 12
 
13 13
 const (
@@ -20,7 +20,7 @@ type SubstitutePathRule struct {
20 20
 	// Directory path will be substituted if it matches `From`.
21 21
 	From string
22 22
 	// Path to which substitution is performed.
23
-	To   string
23
+	To string
24 24
 }
25 25
 
26 26
 // Slice of source code path substitution rules.
@@ -29,9 +29,24 @@ type SubstitutePathRules []SubstitutePathRule
29 29
 // Config defines all configuration options available to be set through the config file.
30 30
 type Config struct {
31 31
 	// Commands aliases.
32
-	Aliases        map[string][]string
32
+	Aliases map[string][]string `yaml:"aliases"`
33 33
 	// Source code path substitution rules.
34 34
 	SubstitutePath SubstitutePathRules `yaml:"substitute-path"`
35
+
36
+	// MaxStringLen is the maximum string length that the commands print,
37
+	// locals, args and vars should read (in verbose mode).
38
+	MaxStringLen *int `yaml:"max-string-len,omitempty"`
39
+	// MaxArrayValues is the maximum number of array items that the commands
40
+	// print, locals, args and vars should read (in verbose mode).
41
+	MaxArrayValues *int `yaml:"max-array-values,omitempty"`
42
+
43
+	// If ShowLocationExpr is true whatis will print the DWARF location
44
+	// expression for its argument.
45
+	ShowLocationExpr bool `yaml:"show-location-expr"`
46
+	
47
+	// Source list line-number color (3/4 bit color codes as defined
48
+	// here: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors)
49
+	SourceListLineColor int `yaml:"source-list-line-color"`
35 50
 }
36 51
 
37 52
 // LoadConfig attempts to populate a Config object from the config.yml file.
@@ -49,8 +64,11 @@ func LoadConfig() *Config {
49 64
 
50 65
 	f, err := os.Open(fullConfigFile)
51 66
 	if err != nil {
52
-		createDefaultConfig(fullConfigFile)
53
-		return nil
67
+		f, err = createDefaultConfig(fullConfigFile)
68
+		if err != nil {
69
+			fmt.Printf("Error creating default config file: %v", err)
70
+			return nil
71
+		}
54 72
 	}
55 73
 	defer func() {
56 74
 		err := f.Close()
@@ -75,22 +93,37 @@ func LoadConfig() *Config {
75 93
 	return &c
76 94
 }
77 95
 
78
-func createDefaultConfig(path string) {
96
+func SaveConfig(conf *Config) error {
97
+	fullConfigFile, err := GetConfigFilePath(configFile)
98
+	if err != nil {
99
+		return err
100
+	}
101
+
102
+	out, err := yaml.Marshal(*conf)
103
+	if err != nil {
104
+		return err
105
+	}
106
+
107
+	f, err := os.Create(fullConfigFile)
108
+	if err != nil {
109
+		return err
110
+	}
111
+	defer f.Close()
112
+
113
+	_, err = f.Write(out)
114
+	return err
115
+}
116
+
117
+func createDefaultConfig(path string) (*os.File, error) {
79 118
 	f, err := os.Create(path)
80 119
 	if err != nil {
81
-		fmt.Printf("Unable to create config file: %v.", err)
82
-		return
120
+		return nil, fmt.Errorf("Unable to create config file: %v.", err)
83 121
 	}
84
-	defer func() {
85
-		err := f.Close()
86
-		if err != nil {
87
-			fmt.Printf("Closing config file failed: %v.", err)
88
-		}
89
-	}()
90 122
 	err = writeDefaultConfig(f)
91 123
 	if err != nil {
92
-		fmt.Printf("Unable to write default configuration: %v.", err)
124
+		return nil, fmt.Errorf("Unable to write default configuration: %v.", err)
93 125
 	}
126
+	return f, nil
94 127
 }
95 128
 
96 129
 func writeDefaultConfig(f *os.File) error {
@@ -100,6 +133,11 @@ func writeDefaultConfig(f *os.File) error {
100 133
 # This is the default configuration file. Available options are provided, but disabled.
101 134
 # Delete the leading hash mark to enable an item.
102 135
 
136
+# Uncomment the following line and set your preferred ANSI foreground color
137
+# for source line numbers in the (list) command (if unset, default is 34,
138
+# dark blue) See https://en.wikipedia.org/wiki/ANSI_escape_code#3/4_bit
139
+# source-list-line-color: 34
140
+
103 141
 # Provided aliases will be added to the default aliases for a given command.
104 142
 aliases:
105 143
   # command: ["alias1", "alias2"]
@@ -111,6 +149,15 @@ aliases:
111 149
 # commands.
112 150
 substitute-path:
113 151
   # - {from: path, to: path}
152
+  
153
+# Maximum number of elements loaded from an array.
154
+# max-array-values: 64
155
+
156
+# Maximum loaded string length.
157
+# max-string-len: 64
158
+
159
+# Uncomment the following line to make the whatis command also print the DWARF location expression of its argument.
160
+# show-location-expr: true
114 161
 `)
115 162
 	return err
116 163
 }

+ 63
- 0
vendor/github.com/derekparker/delve/pkg/config/split.go View File

@@ -0,0 +1,63 @@
1
+package config
2
+
3
+import (
4
+	"bytes"
5
+	"unicode"
6
+)
7
+
8
+// Like strings.Fields but ignores spaces inside areas surrounded
9
+// by the specified quote character.
10
+// To specify a single quote use backslash to escape it: '\''
11
+func SplitQuotedFields(in string, quote rune) []string {
12
+	type stateEnum int
13
+	const (
14
+		inSpace stateEnum = iota
15
+		inField
16
+		inQuote
17
+		inQuoteEscaped
18
+	)
19
+	state := inSpace
20
+	r := []string{}
21
+	var buf bytes.Buffer
22
+
23
+	for _, ch := range in {
24
+		switch state {
25
+		case inSpace:
26
+			if ch == quote {
27
+				state = inQuote
28
+			} else if !unicode.IsSpace(ch) {
29
+				buf.WriteRune(ch)
30
+				state = inField
31
+			}
32
+
33
+		case inField:
34
+			if ch == quote {
35
+				state = inQuote
36
+			} else if unicode.IsSpace(ch) {
37
+				r = append(r, buf.String())
38
+				buf.Reset()
39
+			} else {
40
+				buf.WriteRune(ch)
41
+			}
42
+
43
+		case inQuote:
44
+			if ch == quote {
45
+				state = inField
46
+			} else if ch == '\\' {
47
+				state = inQuoteEscaped
48
+			} else {
49
+				buf.WriteRune(ch)
50
+			}
51
+
52
+		case inQuoteEscaped:
53
+			buf.WriteRune(ch)
54
+			state = inQuote
55
+		}
56
+	}
57
+
58
+	if buf.Len() != 0 {
59
+		r = append(r, buf.String())
60
+	}
61
+
62
+	return r
63
+}

vendor/github.com/derekparker/delve/dwarf/frame/entries.go → vendor/github.com/derekparker/delve/pkg/dwarf/frame/entries.go View File

@@ -17,6 +17,7 @@ type CommonInformationEntry struct {
17 17
 	DataAlignmentFactor   int64
18 18
 	ReturnAddressRegister uint64
19 19
 	InitialInstructions   []byte
20
+	staticBase            uint64
20 21
 }
21 22
 
22 23
 // Represents a Frame Descriptor Entry in the
@@ -25,17 +26,14 @@ type FrameDescriptionEntry struct {
25 26
 	Length       uint32
26 27
 	CIE          *CommonInformationEntry
27 28
 	Instructions []byte
28
-	begin, end   uint64
29
+	begin, size  uint64
29 30
 	order        binary.ByteOrder
30 31
 }
31 32
 
32 33
 // Returns whether or not the given address is within the
33 34
 // bounds of this frame.
34 35
 func (fde *FrameDescriptionEntry) Cover(addr uint64) bool {
35
-	if (addr - fde.begin) < fde.end {
36
-		return true
37
-	}
38
-	return false
36
+	return (addr - fde.begin) < fde.size
39 37
 }
40 38
 
41 39
 // Address of first location for this frame.
@@ -45,7 +43,7 @@ func (fde *FrameDescriptionEntry) Begin() uint64 {
45 43
 
46 44
 // Address of last location for this frame.
47 45
 func (fde *FrameDescriptionEntry) End() uint64 {
48
-	return fde.begin + fde.end
46
+	return fde.begin + fde.size
49 47
 }
50 48
 
51 49
 // Set up frame for the given PC.
@@ -53,43 +51,27 @@ func (fde *FrameDescriptionEntry) EstablishFrame(pc uint64) *FrameContext {
53 51
 	return executeDwarfProgramUntilPC(fde, pc)
54 52
 }
55 53
 
56
-// Return the offset from the current SP that the return address is stored at.
57
-func (fde *FrameDescriptionEntry) ReturnAddressOffset(pc uint64) (frameOffset, returnAddressOffset int64) {
58
-	frame := fde.EstablishFrame(pc)
59
-	return frame.cfa.offset, frame.regs[fde.CIE.ReturnAddressRegister].offset
60
-}
61
-
62 54
 type FrameDescriptionEntries []*FrameDescriptionEntry
63 55
 
64 56
 func NewFrameIndex() FrameDescriptionEntries {
65 57
 	return make(FrameDescriptionEntries, 0, 1000)
66 58
 }
67 59
 
68
-type NoFDEForPCError struct {
60
+type ErrNoFDEForPC struct {
69 61
 	PC uint64
70 62
 }
71 63
 
72
-func (err *NoFDEForPCError) Error() string {
64
+func (err *ErrNoFDEForPC) Error() string {
73 65
 	return fmt.Sprintf("could not find FDE for PC %#v", err.PC)
74 66
 }
75 67
 
76 68
 // Returns the Frame Description Entry for the given PC.
77 69
 func (fdes FrameDescriptionEntries) FDEForPC(pc uint64) (*FrameDescriptionEntry, error) {
78 70
 	idx := sort.Search(len(fdes), func(i int) bool {
79
-		if fdes[i].Cover(pc) {
80
-			return true
81
-		}
82
-		if fdes[i].LessThan(pc) {
83
-			return false
84
-		}
85
-		return true
71
+		return fdes[i].Cover(pc) || fdes[i].Begin() >= pc
86 72
 	})
87
-	if idx == len(fdes) {
88
-		return nil, &NoFDEForPCError{pc}
73
+	if idx == len(fdes) || !fdes[idx].Cover(pc) {
74
+		return nil, &ErrNoFDEForPC{pc}
89 75
 	}
90 76
 	return fdes[idx], nil
91 77
 }
92
-
93
-func (frame *FrameDescriptionEntry) LessThan(pc uint64) bool {
94
-	return frame.End() <= pc
95
-}

vendor/github.com/derekparker/delve/dwarf/frame/expression_constants.go → vendor/github.com/derekparker/delve/pkg/dwarf/frame/expression_constants.go View File


vendor/github.com/derekparker/delve/dwarf/frame/parser.go → vendor/github.com/derekparker/delve/pkg/dwarf/frame/parser.go View File

@@ -7,12 +7,14 @@ import (
7 7
 	"bytes"
8 8
 	"encoding/binary"
9 9
 
10
-	"github.com/derekparker/delve/dwarf/util"
10
+	"github.com/derekparker/delve/pkg/dwarf/util"
11 11
 )
12 12
 
13 13
 type parsefunc func(*parseContext) parsefunc
14 14
 
15 15
 type parseContext struct {
16
+	staticBase uint64
17
+
16 18
 	buf     *bytes.Buffer
17 19
 	entries FrameDescriptionEntries
18 20
 	common  *CommonInformationEntry
@@ -23,10 +25,10 @@ type parseContext struct {
23 25
 // Parse takes in data (a byte slice) and returns a slice of
24 26
 // commonInformationEntry structures. Each commonInformationEntry
25 27
 // has a slice of frameDescriptionEntry structures.
26
-func Parse(data []byte, order binary.ByteOrder) FrameDescriptionEntries {
28
+func Parse(data []byte, order binary.ByteOrder, staticBase uint64) FrameDescriptionEntries {
27 29
 	var (
28 30
 		buf  = bytes.NewBuffer(data)
29
-		pctx = &parseContext{buf: buf, entries: NewFrameIndex()}
31
+		pctx = &parseContext{buf: buf, entries: NewFrameIndex(), staticBase: staticBase}
30 32
 	)
31 33
 
32 34
 	for fn := parselength; buf.Len() != 0; {
@@ -45,12 +47,19 @@ func cieEntry(data []byte) bool {
45 47
 }
46 48
 
47 49
 func parselength(ctx *parseContext) parsefunc {
48
-	var data = ctx.buf.Next(8)
50
+	binary.Read(ctx.buf, binary.LittleEndian, &ctx.length)
51
+
52
+	if ctx.length == 0 {
53
+		// ZERO terminator
54
+		return parselength
55
+	}
56
+
57
+	var data = ctx.buf.Next(4)
49 58
 
50
-	ctx.length = binary.LittleEndian.Uint32(data[:4]) - 4 // take off the length of the CIE id / CIE pointer.
59
+	ctx.length -= 4 // take off the length of the CIE id / CIE pointer.
51 60
 
52
-	if cieEntry(data[4:]) {
53
-		ctx.common = &CommonInformationEntry{Length: ctx.length}
61
+	if cieEntry(data) {
62
+		ctx.common = &CommonInformationEntry{Length: ctx.length, staticBase: ctx.staticBase}
54 63
 		return parseCIE
55 64
 	}
56 65
 
@@ -61,8 +70,8 @@ func parselength(ctx *parseContext) parsefunc {
61 70
 func parseFDE(ctx *parseContext) parsefunc {
62 71
 	r := ctx.buf.Next(int(ctx.length))
63 72
 
64
-	ctx.frame.begin = binary.LittleEndian.Uint64(r[:8])
65
-	ctx.frame.end = binary.LittleEndian.Uint64(r[8:16])
73
+	ctx.frame.begin = binary.LittleEndian.Uint64(r[:8]) + ctx.staticBase
74
+	ctx.frame.size = binary.LittleEndian.Uint64(r[8:16])
66 75
 
67 76
 	// Insert into the tree after setting address range begin
68 77
 	// otherwise compares won't work.

vendor/github.com/derekparker/delve/dwarf/frame/table.go → vendor/github.com/derekparker/delve/pkg/dwarf/frame/table.go View File

@@ -5,41 +5,31 @@ import (
5 5
 	"encoding/binary"
6 6
 	"fmt"
7 7
 
8
-	"github.com/derekparker/delve/dwarf/util"
8
+	"github.com/derekparker/delve/pkg/dwarf/util"
9 9
 )
10 10
 
11
-type CurrentFrameAddress struct {
12
-	register   uint64
13
-	offset     int64
14
-	expression []byte
15
-	rule       byte
16
-}
17
-
18 11
 type DWRule struct {
19
-	rule       byte
20
-	offset     int64
21
-	newreg     uint64
22
-	expression []byte
12
+	Rule       Rule
13
+	Offset     int64
14
+	Reg        uint64
15
+	Expression []byte
23 16
 }
24 17
 
25 18
 type FrameContext struct {
26 19
 	loc           uint64
27 20
 	order         binary.ByteOrder
28 21
 	address       uint64
29
-	cfa           CurrentFrameAddress
30
-	regs          map[uint64]DWRule
22
+	CFA           DWRule
23
+	Regs          map[uint64]DWRule
31 24
 	initialRegs   map[uint64]DWRule
32 25
 	prevRegs      map[uint64]DWRule
33 26
 	buf           *bytes.Buffer
34 27
 	cie           *CommonInformationEntry
28
+	RetAddrReg    uint64
35 29
 	codeAlignment uint64
36 30
 	dataAlignment int64
37 31
 }
38 32
 
39
-func (fctx *FrameContext) CFAOffset() int64 {
40
-	return fctx.cfa.offset
41
-}
42
-
43 33
 // Instructions used to recreate the table from the .debug_frame data.
44 34
 const (
45 35
 	DW_CFA_nop                = 0x0        // No ops
@@ -73,15 +63,19 @@ const (
73 63
 )
74 64
 
75 65
 // Rules defined for register values.
66
+type Rule byte
67
+
76 68
 const (
77
-	rule_undefined = iota
78
-	rule_sameval
79
-	rule_offset
80
-	rule_valoffset
81
-	rule_register
82
-	rule_expression
83
-	rule_valexpression
84
-	rule_architectural
69
+	RuleUndefined Rule = iota
70
+	RuleSameVal
71
+	RuleOffset
72
+	RuleValOffset
73
+	RuleRegister
74
+	RuleExpression
75
+	RuleValExpression
76
+	RuleArchitectural
77
+	RuleCFA          // Value is rule.Reg + rule.Offset
78
+	RuleFramePointer // Value is stored at address rule.Reg + rule.Offset, but only if it's less than the current CFA, otherwise same value
85 79
 )
86 80
 
87 81
 const low_6_offset = 0x3f
@@ -124,7 +118,8 @@ func executeCIEInstructions(cie *CommonInformationEntry) *FrameContext {
124 118
 	copy(initialInstructions, cie.InitialInstructions)
125 119
 	frame := &FrameContext{
126 120
 		cie:           cie,
127
-		regs:          make(map[uint64]DWRule),
121
+		Regs:          make(map[uint64]DWRule),
122
+		RetAddrReg:    cie.ReturnAddressRegister,
128 123
 		initialRegs:   make(map[uint64]DWRule),
129 124
 		prevRegs:      make(map[uint64]DWRule),
130 125
 		codeAlignment: cie.CodeAlignmentFactor,
@@ -142,9 +137,7 @@ func executeDwarfProgramUntilPC(fde *FrameDescriptionEntry, pc uint64) *FrameCon
142 137
 	frame.order = fde.order
143 138
 	frame.loc = fde.Begin()
144 139
 	frame.address = pc
145
-	fdeInstructions := make([]byte, len(fde.Instructions))
146
-	copy(fdeInstructions, fde.Instructions)
147
-	frame.ExecuteUntilPC(fdeInstructions)
140
+	frame.ExecuteUntilPC(fde.Instructions)
148 141
 
149 142
 	return frame
150 143
 }
@@ -161,7 +154,7 @@ func (frame *FrameContext) ExecuteUntilPC(instructions []byte) {
161 154
 	frame.buf.Write(instructions)
162 155
 
163 156
 	// We only need to execute the instructions until
164
-	// ctx.loc > ctx.addess (which is the address we
157
+	// ctx.loc > ctx.address (which is the address we
165 158
 	// are currently at in the traced process).
166 159
 	for frame.address >= frame.loc && frame.buf.Len() > 0 {
167 160
 		executeDwarfInstruction(frame)
@@ -262,7 +255,7 @@ func offset(frame *FrameContext) {
262 255
 		offset, _ = util.DecodeULEB128(frame.buf)
263 256
 	)
264 257
 
265
-	frame.regs[uint64(reg)] = DWRule{offset: int64(offset) * frame.dataAlignment, rule: rule_offset}
258
+	frame.Regs[uint64(reg)] = DWRule{Offset: int64(offset) * frame.dataAlignment, Rule: RuleOffset}
266 259
 }
267 260
 
268 261
 func restore(frame *FrameContext) {
@@ -274,9 +267,9 @@ func restore(frame *FrameContext) {
274 267
 	reg := uint64(b & low_6_offset)
275 268
 	oldrule, ok := frame.initialRegs[reg]
276 269
 	if ok {
277
-		frame.regs[reg] = DWRule{offset: oldrule.offset, rule: rule_offset}
270
+		frame.Regs[reg] = DWRule{Offset: oldrule.Offset, Rule: RuleOffset}
278 271
 	} else {
279
-		frame.regs[reg] = DWRule{rule: rule_undefined}
272
+		frame.Regs[reg] = DWRule{Rule: RuleUndefined}
280 273
 	}
281 274
 }
282 275
 
@@ -284,7 +277,7 @@ func setloc(frame *FrameContext) {
284 277
 	var loc uint64
285 278
 	binary.Read(frame.buf, frame.order, &loc)
286 279
 
287
-	frame.loc = loc
280
+	frame.loc = loc + frame.cie.staticBase
288 281
 }
289 282
 
290 283
 func offsetextended(frame *FrameContext) {
@@ -293,31 +286,31 @@ func offsetextended(frame *FrameContext) {
293 286
 		offset, _ = util.DecodeULEB128(frame.buf)
294 287
 	)
295 288
 
296
-	frame.regs[reg] = DWRule{offset: int64(offset) * frame.dataAlignment, rule: rule_offset}
289
+	frame.Regs[reg] = DWRule{Offset: int64(offset) * frame.dataAlignment, Rule: RuleOffset}
297 290
 }
298 291
 
299 292
 func undefined(frame *FrameContext) {
300 293
 	reg, _ := util.DecodeULEB128(frame.buf)
301
-	frame.regs[reg] = DWRule{rule: rule_undefined}
294
+	frame.Regs[reg] = DWRule{Rule: RuleUndefined}
302 295
 }
303 296
 
304 297
 func samevalue(frame *FrameContext) {
305 298
 	reg, _ := util.DecodeULEB128(frame.buf)
306
-	frame.regs[reg] = DWRule{rule: rule_sameval}
299
+	frame.Regs[reg] = DWRule{Rule: RuleSameVal}
307 300
 }
308 301
 
309 302
 func register(frame *FrameContext) {
310 303
 	reg1, _ := util.DecodeULEB128(frame.buf)
311 304
 	reg2, _ := util.DecodeULEB128(frame.buf)
312
-	frame.regs[reg1] = DWRule{newreg: reg2, rule: rule_register}
305
+	frame.Regs[reg1] = DWRule{Reg: reg2, Rule: RuleRegister}
313 306
 }
314 307
 
315 308
 func rememberstate(frame *FrameContext) {
316
-	frame.prevRegs = frame.regs
309
+	frame.prevRegs = frame.Regs
317 310
 }
318 311
 
319 312
 func restorestate(frame *FrameContext) {
320
-	frame.regs = frame.prevRegs
313
+	frame.Regs = frame.prevRegs
321 314
 }
322 315
 
323 316
 func restoreextended(frame *FrameContext) {
@@ -325,9 +318,9 @@ func restoreextended(frame *FrameContext) {
325 318
 
326 319
 	oldrule, ok := frame.initialRegs[reg]
327 320
 	if ok {
328
-		frame.regs[reg] = DWRule{offset: oldrule.offset, rule: rule_offset}
321
+		frame.Regs[reg] = DWRule{Offset: oldrule.Offset, Rule: RuleOffset}
329 322
 	} else {
330
-		frame.regs[reg] = DWRule{rule: rule_undefined}
323
+		frame.Regs[reg] = DWRule{Rule: RuleUndefined}
331 324
 	}
332 325
 }
333 326
 
@@ -335,32 +328,34 @@ func defcfa(frame *FrameContext) {
335 328
 	reg, _ := util.DecodeULEB128(frame.buf)
336 329
 	offset, _ := util.DecodeULEB128(frame.buf)
337 330
 
338
-	frame.cfa.register = reg
339
-	frame.cfa.offset = int64(offset)
331
+	frame.CFA.Rule = RuleCFA
332
+	frame.CFA.Reg = reg
333
+	frame.CFA.Offset = int64(offset)
340 334
 }
341 335
 
342 336
 func defcfaregister(frame *FrameContext) {
343 337
 	reg, _ := util.DecodeULEB128(frame.buf)
344
-	frame.cfa.register = reg
338
+	frame.CFA.Reg = reg
345 339
 }
346 340
 
347 341
 func defcfaoffset(frame *FrameContext) {
348 342
 	offset, _ := util.DecodeULEB128(frame.buf)
349
-	frame.cfa.offset = int64(offset)
343
+	frame.CFA.Offset = int64(offset)
350 344
 }
351 345
 
352 346
 func defcfasf(frame *FrameContext) {
353 347
 	reg, _ := util.DecodeULEB128(frame.buf)
354 348
 	offset, _ := util.DecodeSLEB128(frame.buf)
355 349
 
356
-	frame.cfa.register = reg
357
-	frame.cfa.offset = offset * frame.dataAlignment
350
+	frame.CFA.Rule = RuleCFA
351
+	frame.CFA.Reg = reg
352
+	frame.CFA.Offset = offset * frame.dataAlignment
358 353
 }
359 354
 
360 355
 func defcfaoffsetsf(frame *FrameContext) {
361 356
 	offset, _ := util.DecodeSLEB128(frame.buf)
362 357
 	offset *= frame.dataAlignment
363
-	frame.cfa.offset = offset
358
+	frame.CFA.Offset = offset
364 359
 }
365 360
 
366 361
 func defcfaexpression(frame *FrameContext) {
@@ -369,8 +364,8 @@ func defcfaexpression(frame *FrameContext) {
369 364
 		expr = frame.buf.Next(int(l))
370 365
 	)
371 366
 
372
-	frame.cfa.expression = expr
373
-	frame.cfa.rule = rule_expression
367
+	frame.CFA.Expression = expr
368
+	frame.CFA.Rule = RuleExpression
374 369
 }
375 370
 
376 371
 func expression(frame *FrameContext) {
@@ -380,7 +375,7 @@ func expression(frame *FrameContext) {
380 375
 		expr   = frame.buf.Next(int(l))
381 376
 	)
382 377
 
383
-	frame.regs[reg] = DWRule{rule: rule_expression, expression: expr}
378
+	frame.Regs[reg] = DWRule{Rule: RuleExpression, Expression: expr}
384 379
 }
385 380
 
386 381
 func offsetextendedsf(frame *FrameContext) {
@@ -389,7 +384,7 @@ func offsetextendedsf(frame *FrameContext) {
389 384
 		offset, _ = util.DecodeSLEB128(frame.buf)
390 385
 	)
391 386
 
392
-	frame.regs[reg] = DWRule{offset: offset * frame.dataAlignment, rule: rule_offset}
387
+	frame.Regs[reg] = DWRule{Offset: offset * frame.dataAlignment, Rule: RuleOffset}
393 388
 }
394 389
 
395 390
 func valoffset(frame *FrameContext) {
@@ -398,7 +393,7 @@ func valoffset(frame *FrameContext) {
398 393
 		offset, _ = util.DecodeULEB128(frame.buf)
399 394
 	)
400 395
 
401
-	frame.regs[reg] = DWRule{offset: int64(offset), rule: rule_valoffset}
396
+	frame.Regs[reg] = DWRule{Offset: int64(offset), Rule: RuleValOffset}
402 397
 }
403 398
 
404 399
 func valoffsetsf(frame *FrameContext) {
@@ -407,7 +402,7 @@ func valoffsetsf(frame *FrameContext) {
407 402
 		offset, _ = util.DecodeSLEB128(frame.buf)
408 403
 	)
409 404
 
410
-	frame.regs[reg] = DWRule{offset: offset * frame.dataAlignment, rule: rule_valoffset}
405
+	frame.Regs[reg] = DWRule{Offset: offset * frame.dataAlignment, Rule: RuleValOffset}
411 406
 }
412 407
 
413 408
 func valexpression(frame *FrameContext) {
@@ -417,7 +412,7 @@ func valexpression(frame *FrameContext) {
417 412
 		expr   = frame.buf.Next(int(l))
418 413
 	)
419 414
 
420
-	frame.regs[reg] = DWRule{rule: rule_valexpression, expression: expr}
415
+	frame.Regs[reg] = DWRule{Rule: RuleValExpression, Expression: expr}
421 416
 }
422 417
 
423 418
 func louser(frame *FrameContext) {

+ 107
- 0
vendor/github.com/derekparker/delve/pkg/dwarf/godwarf/sections.go View File

@@ -0,0 +1,107 @@
1
+package godwarf
2
+
3
+import (
4
+	"bytes"
5
+	"compress/zlib"
6
+	"debug/elf"
7
+	"debug/macho"
8
+	"debug/pe"
9
+	"encoding/binary"
10
+	"fmt"
11
+	"io"
12
+)
13
+
14
+// GetDebugSectionElf returns the data contents of the specified debug
15
+// section, decompressing it if it is compressed.
16
+// For example GetDebugSectionElf("line") will return the contents of
17
+// .debug_line, if .debug_line doesn't exist it will try to return the
18
+// decompressed contents of .zdebug_line.
19
+func GetDebugSectionElf(f *elf.File, name string) ([]byte, error) {
20
+	sec := f.Section(".debug_" + name)
21
+	if sec != nil {
22
+		return sec.Data()
23
+	}
24
+	sec = f.Section(".zdebug_" + name)
25
+	if sec == nil {
26
+		return nil, fmt.Errorf("could not find .debug_%s section", name)
27
+	}
28
+	b, err := sec.Data()
29
+	if err != nil {
30
+		return nil, err
31
+	}
32
+	return decompressMaybe(b)
33
+}
34
+
35
+// GetDebugSectionPE returns the data contents of the specified debug
36
+// section, decompressing it if it is compressed.
37
+// For example GetDebugSectionPE("line") will return the contents of
38
+// .debug_line, if .debug_line doesn't exist it will try to return the
39
+// decompressed contents of .zdebug_line.
40
+func GetDebugSectionPE(f *pe.File, name string) ([]byte, error) {
41
+	sec := f.Section(".debug_" + name)
42
+	if sec != nil {
43
+		return peSectionData(sec)
44
+	}
45
+	sec = f.Section(".zdebug_" + name)
46
+	if sec == nil {
47
+		return nil, fmt.Errorf("could not find .debug_%s section", name)
48
+	}
49
+	b, err := peSectionData(sec)
50
+	if err != nil {
51
+		return nil, err
52
+	}
53
+	return decompressMaybe(b)
54
+}
55
+
56
+func peSectionData(sec *pe.Section) ([]byte, error) {
57
+	b, err := sec.Data()
58
+	if err != nil {
59
+		return nil, err
60
+	}
61
+	if 0 < sec.VirtualSize && sec.VirtualSize < sec.Size {
62
+		b = b[:sec.VirtualSize]
63
+	}
64
+	return b, nil
65
+}
66
+
67
+// GetDebugSectionMacho returns the data contents of the specified debug
68
+// section, decompressing it if it is compressed.
69
+// For example GetDebugSectionMacho("line") will return the contents of
70
+// __debug_line, if __debug_line doesn't exist it will try to return the
71
+// decompressed contents of __zdebug_line.
72
+func GetDebugSectionMacho(f *macho.File, name string) ([]byte, error) {
73
+	sec := f.Section("__debug_" + name)
74
+	if sec != nil {
75
+		return sec.Data()
76
+	}
77
+	sec = f.Section("__zdebug_" + name)
78
+	if sec == nil {
79
+		return nil, fmt.Errorf("could not find .debug_%s section", name)
80
+	}
81
+	b, err := sec.Data()
82
+	if err != nil {
83
+		return nil, err
84
+	}
85
+	return decompressMaybe(b)
86
+}
87
+
88
+func decompressMaybe(b []byte) ([]byte, error) {
89
+	if len(b) < 12 || string(b[:4]) != "ZLIB" {
90
+		// not compressed
91
+		return b, nil
92
+	}
93
+
94
+	dlen := binary.BigEndian.Uint64(b[4:12])
95
+	dbuf := make([]byte, dlen)
96
+	r, err := zlib.NewReader(bytes.NewBuffer(b[12:]))
97
+	if err != nil {
98
+		return nil, err
99
+	}
100
+	if _, err := io.ReadFull(r, dbuf); err != nil {
101
+		return nil, err
102
+	}
103
+	if err := r.Close(); err != nil {
104
+		return nil, err
105
+	}
106
+	return dbuf, nil
107
+}

vendor/golang.org/x/debug/dwarf/type.go → vendor/github.com/derekparker/delve/pkg/dwarf/godwarf/type.go View File

@@ -6,16 +6,44 @@
6 6
 // The format is heavily biased toward C, but for simplicity
7 7
 // the String methods use a pseudo-Go syntax.
8 8
 
9
-package dwarf
9
+// Borrowed from golang.org/x/debug/dwarf/type.go
10
+
11
+package godwarf
10 12
 
11 13
 import (
14
+	"debug/dwarf"
12 15
 	"fmt"
13 16
 	"reflect"
14 17
 	"strconv"
18
+
19
+	"github.com/derekparker/delve/pkg/dwarf/op"
20
+	"github.com/derekparker/delve/pkg/dwarf/util"
21
+)
22
+
23
+const (
24
+	AttrGoKind          dwarf.Attr = 0x2900
25
+	AttrGoKey           dwarf.Attr = 0x2901
26
+	AttrGoElem          dwarf.Attr = 0x2902
27
+	AttrGoEmbeddedField dwarf.Attr = 0x2903
28
+	AttrGoRuntimeType   dwarf.Attr = 0x2904
29
+)
30
+
31
+// Basic type encodings -- the value for AttrEncoding in a TagBaseType Entry.
32
+const (
33
+	encAddress        = 0x01
34
+	encBoolean        = 0x02
35
+	encComplexFloat   = 0x03
36
+	encFloat          = 0x04
37
+	encSigned         = 0x05
38
+	encSignedChar     = 0x06
39
+	encUnsigned       = 0x07
40
+	encUnsignedChar   = 0x08
41
+	encImaginaryFloat = 0x09
15 42
 )
16 43
 
17 44
 // A Type conventionally represents a pointer to any of the
18 45
 // specific Type structures (CharType, StructType, etc.).
46
+//TODO: remove this use dwarf.Type
19 47
 type Type interface {
20 48
 	Common() *CommonType
21 49
 	String() string
@@ -29,7 +57,7 @@ type CommonType struct {
29 57
 	ByteSize    int64        // size of value of this type, in bytes
30 58
 	Name        string       // name that can be used to refer to type
31 59
 	ReflectKind reflect.Kind // the reflect kind of the type.
32
-	Offset      Offset       // the offset at which this type was read
60
+	Offset      dwarf.Offset // the offset at which this type was read
33 61
 }
34 62
 
35 63
 func (c *CommonType) Common() *CommonType { return c }
@@ -158,6 +186,7 @@ type StructField struct {
158 186
 	ByteSize   int64
159 187
 	BitOffset  int64 // within the ByteSize bytes at ByteOffset
160 188
 	BitSize    int64 // zero if not a bit field
189
+	Embedded   bool
161 190
 }
162 191
 
163 192
 func (t *StructType) String() string {
@@ -329,31 +358,19 @@ func (t *ChanType) String() string {
329 358
 	return "chan " + t.ElemType.String()
330 359
 }
331 360
 
332
-// typeReader is used to read from either the info section or the
333
-// types section.
334
-type typeReader interface {
335
-	Seek(Offset)
336
-	Next() (*Entry, error)
337
-	clone() typeReader
338
-	offset() Offset
339
-	// AddressSize returns the size in bytes of addresses in the current
340
-	// compilation unit.
341
-	AddressSize() int
342
-}
343
-
344 361
 // Type reads the type at off in the DWARF ``info'' section.
345
-func (d *Data) Type(off Offset) (Type, error) {
346
-	return d.readType("info", d.Reader(), off, d.typeCache)
362
+func ReadType(d *dwarf.Data, off dwarf.Offset, typeCache map[dwarf.Offset]Type) (Type, error) {
363
+	return readType(d, "info", d.Reader(), off, typeCache)
347 364
 }
348 365
 
349
-func getKind(e *Entry) reflect.Kind {
366
+func getKind(e *dwarf.Entry) reflect.Kind {
350 367
 	integer, _ := e.Val(AttrGoKind).(int64)
351 368
 	return reflect.Kind(integer)
352 369
 }
353 370
 
354 371
 // readType reads a type from r at off of name using and updating a
355 372
 // type cache.
356
-func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Offset]Type) (Type, error) {
373
+func readType(d *dwarf.Data, name string, r *dwarf.Reader, off dwarf.Offset, typeCache map[dwarf.Offset]Type) (Type, error) {
357 374
 	if t, ok := typeCache[off]; ok {
358 375
 		return t, nil
359 376
 	}
@@ -364,10 +381,10 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
364 381
 	}
365 382
 	addressSize := r.AddressSize()
366 383
 	if e == nil || e.Offset != off {
367
-		return nil, DecodeError{name, off, "no type at offset"}
384
+		return nil, dwarf.DecodeError{name, off, "no type at offset"}
368 385
 	}
369 386
 
370
-	// Parse type from Entry.
387
+	// Parse type from dwarf.Entry.
371 388
 	// Must always set typeCache[off] before calling
372 389
 	// d.Type recursively, to handle circular types correctly.
373 390
 	var typ Type
@@ -375,7 +392,7 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
375 392
 	nextDepth := 0
376 393
 
377 394
 	// Get next child; set err if error happens.
378
-	next := func() *Entry {
395
+	next := func() *dwarf.Entry {
379 396
 		if !e.Children {
380 397
 			return nil
381 398
 		}
@@ -390,10 +407,6 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
390 407
 				err = err1
391 408
 				return nil
392 409
 			}
393
-			if kid == nil {
394
-				err = DecodeError{name, r.offset(), "unexpected end of DWARF entries"}
395
-				return nil
396
-			}
397 410
 			if kid.Tag == 0 {
398 411
 				if nextDepth > 0 {
399 412
 					nextDepth--
@@ -411,20 +424,19 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
411 424
 		}
412 425
 	}
413 426
 
414
-	// Get Type referred to by Entry's attr.
427
+	// Get Type referred to by dwarf.Entry's attr.
415 428
 	// Set err if error happens.  Not having a type is an error.
416
-	typeOf := func(e *Entry, attr Attr) Type {
429
+	typeOf := func(e *dwarf.Entry, attr dwarf.Attr) Type {
417 430
 		tval := e.Val(attr)
418 431
 		var t Type
419 432
 		switch toff := tval.(type) {
420
-		case Offset:
421
-			if t, err = d.readType(name, r.clone(), toff, typeCache); err != nil {
433
+		case dwarf.Offset:
434
+			if t, err = readType(d, name, d.Reader(), toff, typeCache); err != nil {
422 435
 				return nil
423 436
 			}
424 437
 		case uint64:
425
-			if t, err = d.sigToType(toff); err != nil {
426
-				return nil
427
-			}
438
+			err = dwarf.DecodeError{name, e.Offset, "DWARFv4 section debug_types unsupported"}
439
+			return nil
428 440
 		default:
429 441
 			// It appears that no Type means "void".
430 442
 			return new(VoidType)
@@ -433,7 +445,7 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
433 445
 	}
434 446
 
435 447
 	switch e.Tag {
436
-	case TagArrayType:
448
+	case dwarf.TagArrayType:
437 449
 		// Multi-dimensional array.  (DWARF v2 §5.4)
438 450
 		// Attributes:
439 451
 		//	AttrType:subtype [required]
@@ -444,16 +456,16 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
444 456
 		//	TagSubrangeType or TagEnumerationType giving one dimension.
445 457
 		//	dimensions are in left to right order.
446 458
 		t := new(ArrayType)
447
-		t.Name, _ = e.Val(AttrName).(string)
459
+		t.Name, _ = e.Val(dwarf.AttrName).(string)
448 460
 		t.ReflectKind = getKind(e)
449 461
 		typ = t
450 462
 		typeCache[off] = t
451
-		if t.Type = typeOf(e, AttrType); err != nil {
463
+		if t.Type = typeOf(e, dwarf.AttrType); err != nil {
452 464
 			goto Error
453 465
 		}
454
-		if bytes, ok := e.Val(AttrStride).(int64); ok {
466
+		if bytes, ok := e.Val(dwarf.AttrStride).(int64); ok {
455 467
 			t.StrideBitSize = 8 * bytes
456
-		} else if bits, ok := e.Val(AttrStrideSize).(int64); ok {
468
+		} else if bits, ok := e.Val(dwarf.AttrStrideSize).(int64); ok {
457 469
 			t.StrideBitSize = bits
458 470
 		} else {
459 471
 			// If there's no stride specified, assume it's the size of the
@@ -467,11 +479,11 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
467 479
 			// TODO(rsc): Can also be TagEnumerationType
468 480
 			// but haven't seen that in the wild yet.
469 481
 			switch kid.Tag {
470
-			case TagSubrangeType:
471
-				count, ok := kid.Val(AttrCount).(int64)
482
+			case dwarf.TagSubrangeType:
483
+				count, ok := kid.Val(dwarf.AttrCount).(int64)
472 484
 				if !ok {
473 485
 					// Old binaries may have an upper bound instead.
474
-					count, ok = kid.Val(AttrUpperBound).(int64)
486
+					count, ok = kid.Val(dwarf.AttrUpperBound).(int64)
475 487
 					if ok {
476 488
 						count++ // Length is one more than upper bound.
477 489
 					} else {
@@ -486,8 +498,8 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
486 498
 					t.Type = &ArrayType{Type: t.Type, Count: count}
487 499
 				}
488 500
 				ndim++
489
-			case TagEnumerationType:
490
-				err = DecodeError{name, kid.Offset, "cannot handle enumeration type as array bound"}
501
+			case dwarf.TagEnumerationType:
502
+				err = dwarf.DecodeError{name, kid.Offset, "cannot handle enumeration type as array bound"}
491 503
 				goto Error
492 504
 			}
493 505
 		}
@@ -496,7 +508,7 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
496 508
 			t.Count = -1
497 509
 		}
498 510
 
499
-	case TagBaseType:
511
+	case dwarf.TagBaseType:
500 512
 		// Basic type.  (DWARF v2 §5.1)
501 513
 		// Attributes:
502 514
 		//	AttrName: name of base type in programming language of the compilation unit [required]
@@ -504,15 +516,15 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
504 516
 		//	AttrByteSize: size of type in bytes [required]
505 517
 		//	AttrBitOffset: for sub-byte types, size in bits
506 518
 		//	AttrBitSize: for sub-byte types, bit offset of high order bit in the AttrByteSize bytes
507
-		name, _ := e.Val(AttrName).(string)
508
-		enc, ok := e.Val(AttrEncoding).(int64)
519
+		name, _ := e.Val(dwarf.AttrName).(string)
520
+		enc, ok := e.Val(dwarf.AttrEncoding).(int64)
509 521
 		if !ok {
510
-			err = DecodeError{name, e.Offset, "missing encoding attribute for " + name}
522
+			err = dwarf.DecodeError{name, e.Offset, "missing encoding attribute for " + name}
511 523
 			goto Error
512 524
 		}
513 525
 		switch enc {
514 526
 		default:
515
-			err = DecodeError{name, e.Offset, "unrecognized encoding attribute value"}
527
+			err = dwarf.DecodeError{name, e.Offset, "unrecognized encoding attribute value"}
516 528
 			goto Error
517 529
 
518 530
 		case encAddress:
@@ -525,7 +537,7 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
525 537
 				// clang writes out 'complex' instead of 'complex float' or 'complex double'.
526 538
 				// clang also writes out a byte size that we can use to distinguish.
527 539
 				// See issue 8694.
528
-				switch byteSize, _ := e.Val(AttrByteSize).(int64); byteSize {
540
+				switch byteSize, _ := e.Val(dwarf.AttrByteSize).(int64); byteSize {
529 541
 				case 8:
530 542
 					name = "complex float"
531 543
 				case 16:
@@ -548,11 +560,11 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
548 560
 			Basic() *BasicType
549 561
 		}).Basic()
550 562
 		t.Name = name
551
-		t.BitSize, _ = e.Val(AttrBitSize).(int64)
552
-		t.BitOffset, _ = e.Val(AttrBitOffset).(int64)
563
+		t.BitSize, _ = e.Val(dwarf.AttrBitSize).(int64)
564
+		t.BitOffset, _ = e.Val(dwarf.AttrBitOffset).(int64)
553 565
 		t.ReflectKind = getKind(e)
554 566
 
555
-	case TagClassType, TagStructType, TagUnionType:
567
+	case dwarf.TagClassType, dwarf.TagStructType, dwarf.TagUnionType:
556 568
 		// Structure, union, or class type.  (DWARF v2 §5.5)
557 569
 		// Also Slices and Strings (Go-specific).
558 570
 		// Attributes:
@@ -586,26 +598,26 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
586 598
 		}
587 599
 		typeCache[off] = typ
588 600
 		switch e.Tag {
589
-		case TagClassType:
601
+		case dwarf.TagClassType:
590 602
 			t.Kind = "class"
591
-		case TagStructType:
603
+		case dwarf.TagStructType:
592 604
 			t.Kind = "struct"
593
-		case TagUnionType:
605
+		case dwarf.TagUnionType:
594 606
 			t.Kind = "union"
595 607
 		}
596
-		t.Name, _ = e.Val(AttrName).(string)
597
-		t.StructName, _ = e.Val(AttrName).(string)
598
-		t.Incomplete = e.Val(AttrDeclaration) != nil
608
+		t.Name, _ = e.Val(dwarf.AttrName).(string)
609
+		t.StructName, _ = e.Val(dwarf.AttrName).(string)
610
+		t.Incomplete = e.Val(dwarf.AttrDeclaration) != nil
599 611
 		t.Field = make([]*StructField, 0, 8)
600 612
 		var lastFieldType Type
601 613
 		var lastFieldBitOffset int64
602 614
 		for kid := next(); kid != nil; kid = next() {
603
-			if kid.Tag == TagMember {
615
+			if kid.Tag == dwarf.TagMember {
604 616
 				f := new(StructField)
605
-				if f.Type = typeOf(kid, AttrType); err != nil {
617
+				if f.Type = typeOf(kid, dwarf.AttrType); err != nil {
606 618
 					goto Error
607 619
 				}
608
-				switch loc := kid.Val(AttrDataMemberLoc).(type) {
620
+				switch loc := kid.Val(dwarf.AttrDataMemberLoc).(type) {
609 621
 				case []byte:
610 622
 					// TODO: Should have original compilation
611 623
 					// unit here, not unknownFormat.
@@ -613,28 +625,28 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
613 625
 						// Empty exprloc. f.ByteOffset=0.
614 626
 						break
615 627
 					}
616
-					b := makeBuf(d, unknownFormat{}, "location", 0, loc)
617
-					op := b.uint8()
618
-					switch op {
619
-					case opPlusUconst:
628
+					b := util.MakeBuf(d, util.UnknownFormat{}, "location", 0, loc)
629
+					op_ := op.Opcode(b.Uint8())
630
+					switch op_ {
631
+					case op.DW_OP_plus_uconst:
620 632
 						// Handle opcode sequence [DW_OP_plus_uconst <uleb128>]
621
-						f.ByteOffset = int64(b.uint())
622
-						b.assertEmpty()
623
-					case opConsts:
633
+						f.ByteOffset = int64(b.Uint())
634
+						b.AssertEmpty()
635
+					case op.DW_OP_consts:
624 636
 						// Handle opcode sequence [DW_OP_consts <sleb128> DW_OP_plus]
625
-						f.ByteOffset = b.int()
626
-						op = b.uint8()
627
-						if op != opPlus {
628
-							err = DecodeError{name, kid.Offset, fmt.Sprintf("unexpected opcode 0x%x", op)}
637
+						f.ByteOffset = b.Int()
638
+						op_ = op.Opcode(b.Uint8())
639
+						if op_ != op.DW_OP_plus {
640
+							err = dwarf.DecodeError{name, kid.Offset, fmt.Sprintf("unexpected opcode 0x%x", op_)}
629 641
 							goto Error
630 642
 						}
631
-						b.assertEmpty()
643
+						b.AssertEmpty()
632 644
 					default:
633
-						err = DecodeError{name, kid.Offset, fmt.Sprintf("unexpected opcode 0x%x", op)}
645
+						err = dwarf.DecodeError{name, kid.Offset, fmt.Sprintf("unexpected opcode 0x%x", op_)}
634 646
 						goto Error
635 647
 					}
636
-					if b.err != nil {
637
-						err = b.err
648
+					if b.Err != nil {
649
+						err = b.Err
638 650
 						goto Error
639 651
 					}
640 652
 				case int64:
@@ -642,10 +654,11 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
642 654
 				}
643 655
 
644 656
 				haveBitOffset := false
645
-				f.Name, _ = kid.Val(AttrName).(string)
646
-				f.ByteSize, _ = kid.Val(AttrByteSize).(int64)
647
-				f.BitOffset, haveBitOffset = kid.Val(AttrBitOffset).(int64)
648
-				f.BitSize, _ = kid.Val(AttrBitSize).(int64)
657
+				f.Name, _ = kid.Val(dwarf.AttrName).(string)
658
+				f.ByteSize, _ = kid.Val(dwarf.AttrByteSize).(int64)
659
+				f.BitOffset, haveBitOffset = kid.Val(dwarf.AttrBitOffset).(int64)
660
+				f.BitSize, _ = kid.Val(dwarf.AttrBitSize).(int64)
661
+				f.Embedded, _ = kid.Val(AttrGoEmbeddedField).(bool)
649 662
 				t.Field = append(t.Field, f)
650 663
 
651 664
 				bito := f.BitOffset
@@ -662,35 +675,35 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
662 675
 			}
663 676
 		}
664 677
 		if t.Kind != "union" {
665
-			b, ok := e.Val(AttrByteSize).(int64)
678
+			b, ok := e.Val(dwarf.AttrByteSize).(int64)
666 679
 			if ok && b*8 == lastFieldBitOffset {
667 680
 				// Final field must be zero width.  Fix array length.
668 681
 				zeroArray(lastFieldType)
669 682
 			}
670 683
 		}
671 684
 
672
-	case TagConstType, TagVolatileType, TagRestrictType:
685
+	case dwarf.TagConstType, dwarf.TagVolatileType, dwarf.TagRestrictType:
673 686
 		// Type modifier (DWARF v2 §5.2)
674 687
 		// Attributes:
675 688
 		//	AttrType: subtype
676 689
 		t := new(QualType)
677
-		t.Name, _ = e.Val(AttrName).(string)
690
+		t.Name, _ = e.Val(dwarf.AttrName).(string)
678 691
 		t.ReflectKind = getKind(e)
679 692
 		typ = t
680 693
 		typeCache[off] = t
681
-		if t.Type = typeOf(e, AttrType); err != nil {
694
+		if t.Type = typeOf(e, dwarf.AttrType); err != nil {
682 695
 			goto Error
683 696
 		}
684 697
 		switch e.Tag {
685
-		case TagConstType:
698
+		case dwarf.TagConstType:
686 699
 			t.Qual = "const"
687
-		case TagRestrictType:
700
+		case dwarf.TagRestrictType:
688 701
 			t.Qual = "restrict"
689
-		case TagVolatileType:
702
+		case dwarf.TagVolatileType:
690 703
 			t.Qual = "volatile"
691 704
 		}
692 705
 
693
-	case TagEnumerationType:
706
+	case dwarf.TagEnumerationType:
694 707
 		// Enumeration type (DWARF v2 §5.6)
695 708
 		// Attributes:
696 709
 		//	AttrName: enum name if any
@@ -703,14 +716,14 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
703 716
 		t.ReflectKind = getKind(e)
704 717
 		typ = t
705 718
 		typeCache[off] = t
706
-		t.Name, _ = e.Val(AttrName).(string)
707
-		t.EnumName, _ = e.Val(AttrName).(string)
719
+		t.Name, _ = e.Val(dwarf.AttrName).(string)
720
+		t.EnumName, _ = e.Val(dwarf.AttrName).(string)
708 721
 		t.Val = make([]*EnumValue, 0, 8)
709 722
 		for kid := next(); kid != nil; kid = next() {
710
-			if kid.Tag == TagEnumerator {
723
+			if kid.Tag == dwarf.TagEnumerator {
711 724
 				f := new(EnumValue)
712
-				f.Name, _ = kid.Val(AttrName).(string)
713
-				f.Val, _ = kid.Val(AttrConstValue).(int64)
725
+				f.Name, _ = kid.Val(dwarf.AttrName).(string)
726
+				f.Val, _ = kid.Val(dwarf.AttrConstValue).(int64)
714 727
 				n := len(t.Val)
715 728
 				if n >= cap(t.Val) {
716 729
 					val := make([]*EnumValue, n, n*2)
@@ -722,23 +735,23 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
722 735
 			}
723 736
 		}
724 737
 
725
-	case TagPointerType:
738
+	case dwarf.TagPointerType:
726 739
 		// Type modifier (DWARF v2 §5.2)
727 740
 		// Attributes:
728 741
 		//	AttrType: subtype [not required!  void* has no AttrType]
729 742
 		//	AttrAddrClass: address class [ignored]
730 743
 		t := new(PtrType)
731
-		t.Name, _ = e.Val(AttrName).(string)
744
+		t.Name, _ = e.Val(dwarf.AttrName).(string)
732 745
 		t.ReflectKind = getKind(e)
733 746
 		typ = t
734 747
 		typeCache[off] = t
735
-		if e.Val(AttrType) == nil {
748
+		if e.Val(dwarf.AttrType) == nil {
736 749
 			t.Type = &VoidType{}
737 750
 			break
738 751
 		}
739
-		t.Type = typeOf(e, AttrType)
752
+		t.Type = typeOf(e, dwarf.AttrType)
740 753
 
741
-	case TagSubroutineType:
754
+	case dwarf.TagSubroutineType:
742 755
 		// Subroutine type.  (DWARF v2 §5.7)
743 756
 		// Attributes:
744 757
 		//	AttrType: type of return value if any
@@ -749,11 +762,11 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
749 762
 		//		AttrType: type of parameter
750 763
 		//	TagUnspecifiedParameter: final ...
751 764
 		t := new(FuncType)
752
-		t.Name, _ = e.Val(AttrName).(string)
765
+		t.Name, _ = e.Val(dwarf.AttrName).(string)
753 766
 		t.ReflectKind = getKind(e)
754 767
 		typ = t
755 768
 		typeCache[off] = t
756
-		if t.ReturnType = typeOf(e, AttrType); err != nil {
769
+		if t.ReturnType = typeOf(e, dwarf.AttrType); err != nil {
757 770
 			goto Error
758 771
 		}
759 772
 		t.ParamType = make([]Type, 0, 8)
@@ -762,17 +775,17 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
762 775
 			switch kid.Tag {
763 776
 			default:
764 777
 				continue
765
-			case TagFormalParameter:
766
-				if tkid = typeOf(kid, AttrType); err != nil {
778
+			case dwarf.TagFormalParameter:
779
+				if tkid = typeOf(kid, dwarf.AttrType); err != nil {
767 780
 					goto Error
768 781
 				}
769
-			case TagUnspecifiedParameters:
782
+			case dwarf.TagUnspecifiedParameters:
770 783
 				tkid = &DotDotDotType{}
771 784
 			}
772 785
 			t.ParamType = append(t.ParamType, tkid)
773 786
 		}
774 787
 
775
-	case TagTypedef:
788
+	case dwarf.TagTypedef:
776 789
 		// Typedef (DWARF v2 §5.3)
777 790
 		// Also maps and channels (Go-specific).
778 791
 		// Attributes:
@@ -802,17 +815,17 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
802 815
 			typ = t
803 816
 		}
804 817
 		typeCache[off] = typ
805
-		t.Name, _ = e.Val(AttrName).(string)
806
-		t.Type = typeOf(e, AttrType)
818
+		t.Name, _ = e.Val(dwarf.AttrName).(string)
819
+		t.Type = typeOf(e, dwarf.AttrType)
807 820
 
808
-	case TagUnspecifiedType:
821
+	case dwarf.TagUnspecifiedType:
809 822
 		// Unspecified type (DWARF v3 §5.2)
810 823
 		// Attributes:
811 824
 		//      AttrName: name
812 825
 		t := new(UnspecifiedType)
813 826
 		typ = t
814 827
 		typeCache[off] = t
815
-		t.Name, _ = e.Val(AttrName).(string)
828
+		t.Name, _ = e.Val(dwarf.AttrName).(string)
816 829
 	}
817 830
 
818 831
 	if err != nil {
@@ -822,7 +835,7 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
822 835
 	typ.Common().Offset = off
823 836
 
824 837
 	{
825
-		b, ok := e.Val(AttrByteSize).(int64)
838
+		b, ok := e.Val(dwarf.AttrByteSize).(int64)
826 839
 		if !ok {
827 840
 			b = -1
828 841
 			switch t := typ.(type) {
@@ -836,6 +849,9 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
836 849
 				b = t.Type.Size()
837 850
 			case *PtrType:
838 851
 				b = int64(addressSize)
852
+			case *FuncType:
853
+				// on Go < 1.10 function types do not have a DW_AT_byte_size attribute.
854
+				b = int64(addressSize)
839 855
 			}
840 856
 		}
841 857
 		typ.Common().ByteSize = b

+ 152
- 0
vendor/github.com/derekparker/delve/pkg/dwarf/line/line_parser.go View File

@@ -0,0 +1,152 @@
1
+package line
2
+
3
+import (
4
+	"bytes"
5
+	"encoding/binary"
6
+	"path/filepath"
7
+
8
+	"github.com/derekparker/delve/pkg/dwarf/util"
9
+)
10
+
11
+type DebugLinePrologue struct {
12
+	UnitLength     uint32
13
+	Version        uint16
14
+	Length         uint32
15
+	MinInstrLength uint8
16
+	InitialIsStmt  uint8
17
+	LineBase       int8
18
+	LineRange      uint8
19
+	OpcodeBase     uint8
20
+	StdOpLengths   []uint8
21
+}
22
+
23
+type DebugLineInfo struct {
24
+	Prologue     *DebugLinePrologue
25
+	IncludeDirs  []string
26
+	FileNames    []*FileEntry
27
+	Instructions []byte
28
+	Lookup       map[string]*FileEntry
29
+
30
+	Logf func(string, ...interface{})
31
+
32
+	// stateMachineCache[pc] is a state machine stopped at pc
33
+	stateMachineCache map[uint64]*StateMachine
34
+
35
+	// lastMachineCache[pc] is a state machine stopped at an address after pc
36
+	lastMachineCache map[uint64]*StateMachine
37
+	
38
+	// staticBase is the address at which the executable is loaded, 0 for non-PIEs
39
+	staticBase uint64
40
+}
41
+
42
+type FileEntry struct {
43
+	Path        string
44
+	DirIdx      uint64
45
+	LastModTime uint64
46
+	Length      uint64
47
+}
48
+
49
+type DebugLines []*DebugLineInfo
50
+
51
+// ParseAll parses all debug_line segments found in data
52
+func ParseAll(data []byte, logfn func(string, ...interface{}), staticBase uint64) DebugLines {
53
+	var (
54
+		lines = make(DebugLines, 0)
55
+		buf   = bytes.NewBuffer(data)
56
+	)
57
+
58
+	// We have to parse multiple file name tables here.
59
+	for buf.Len() > 0 {
60
+		lines = append(lines, Parse("", buf, logfn, staticBase))
61
+	}
62
+
63
+	return lines
64
+}
65
+
66
+// Parse parses a single debug_line segment from buf. Compdir is the
67
+// DW_AT_comp_dir attribute of the associated compile unit.
68
+func Parse(compdir string, buf *bytes.Buffer, logfn func(string, ...interface{}), staticBase uint64) *DebugLineInfo {
69
+	dbl := new(DebugLineInfo)
70
+	dbl.Logf = logfn
71
+	dbl.staticBase = staticBase