File: moduledata.go

package info (click to toggle)
delve 1.24.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 14,092 kB
  • sloc: ansic: 111,943; sh: 169; asm: 141; makefile: 43; python: 23
file content (79 lines) | stat: -rw-r--r-- 1,765 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package proc

// ModuleData counterpart to runtime.moduleData
type ModuleData struct {
	text, etext   uint64
	types, etypes uint64
	typemapVar    *Variable
}

func LoadModuleData(bi *BinaryInfo, mem MemoryReadWriter) ([]ModuleData, error) {
	// +rtype -var firstmoduledata moduledata
	// +rtype -field moduledata.text uintptr
	// +rtype -field moduledata.types uintptr

	scope := globalScope(nil, bi, bi.Images[0], mem)
	var md *Variable
	md, err := scope.findGlobal("runtime", "firstmoduledata")
	if err != nil {
		return nil, err
	}

	r := []ModuleData{}

	for md.Addr != 0 {
		const (
			typesField   = "types"
			etypesField  = "etypes"
			textField    = "text"
			etextField   = "etext"
			nextField    = "next"
			typemapField = "typemap"
		)
		vars := map[string]*Variable{}

		for _, fieldName := range []string{typesField, etypesField, textField, etextField, nextField, typemapField} {
			var err error
			vars[fieldName], err = md.structMember(fieldName)
			if err != nil {
				return nil, err
			}
		}

		var err error

		touint := func(name string) (ret uint64) {
			if err == nil {
				var n uint64
				n, err = vars[name].asUint()
				ret = n
			}
			return ret
		}

		r = append(r, ModuleData{
			types: touint(typesField), etypes: touint(etypesField),
			text: touint(textField), etext: touint(etextField),
			typemapVar: vars[typemapField],
		})
		if err != nil {
			return nil, err
		}

		md = vars[nextField].maybeDereference()
		if md.Unreadable != nil {
			return nil, md.Unreadable
		}
	}

	return r, nil
}

func findModuleDataForType(bi *BinaryInfo, mds []ModuleData, typeAddr uint64, mem MemoryReadWriter) *ModuleData {
	for i := range mds {
		if typeAddr >= mds[i].types && typeAddr < mds[i].etypes {
			return &mds[i]
		}
	}
	return nil
}