-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
btfhub.go
151 lines (125 loc) · 4.09 KB
/
btfhub.go
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2016-present Datadog, Inc.
//go:build linux
// Package constantfetch holds constantfetch related files
package constantfetch
import (
_ "embed"
"encoding/json"
"fmt"
"runtime"
"strings"
"github.com/DataDog/datadog-agent/pkg/security/ebpf/kernel"
)
//go:embed btfhub/constants.json
var btfhubConstants []byte
// BTFHubConstantFetcher is a constant fetcher based on BTFHub constants
type BTFHubConstantFetcher struct {
kernelVersion *kernel.Version
inStore map[string]uint64
res map[string]uint64
}
var archMapping = map[string]string{
"amd64": "x86_64",
"arm64": "arm64",
}
// NewBTFHubConstantFetcher returns a new BTFHubConstantFetcher
func NewBTFHubConstantFetcher(kv *kernel.Version) (*BTFHubConstantFetcher, error) {
fetcher := &BTFHubConstantFetcher{
kernelVersion: kv,
inStore: make(map[string]uint64),
res: make(map[string]uint64),
}
currentKernelInfos, err := newKernelInfos(kv)
if err != nil {
return nil, fmt.Errorf("failed to collect current kernel infos: %w", err)
}
var constantsInfos BTFHubConstants
if err := json.Unmarshal(btfhubConstants, &constantsInfos); err != nil {
return nil, err
}
for _, kernel := range constantsInfos.Kernels {
if kernel.Distribution == currentKernelInfos.distribution && kernel.DistribVersion == currentKernelInfos.distribVersion && kernel.Arch == currentKernelInfos.arch && kernel.UnameRelease == currentKernelInfos.unameRelease {
fetcher.inStore = constantsInfos.Constants[kernel.ConstantsIndex]
break
}
}
return fetcher, nil
}
func (f *BTFHubConstantFetcher) String() string {
return "btfhub"
}
// HasConstantsInStore returns true if there is constants in store in BTFHub
func (f *BTFHubConstantFetcher) HasConstantsInStore() bool {
return len(f.inStore) != 0
}
func (f *BTFHubConstantFetcher) appendRequest(id string) {
if value, ok := f.inStore[id]; ok {
f.res[id] = value
} else {
f.res[id] = ErrorSentinel
}
}
// AppendSizeofRequest appends a sizeof request
func (f *BTFHubConstantFetcher) AppendSizeofRequest(id, _, _ string) {
f.appendRequest(id)
}
// AppendOffsetofRequest appends an offset request
func (f *BTFHubConstantFetcher) AppendOffsetofRequest(id, _, _, _ string) {
f.appendRequest(id)
}
// FinishAndGetResults returns the results
func (f *BTFHubConstantFetcher) FinishAndGetResults() (map[string]uint64, error) {
return f.res, nil
}
type kernelInfos struct {
distribution string
distribVersion string
arch string
unameRelease string
}
func newKernelInfos(kv *kernel.Version) (*kernelInfos, error) {
distribution, ok := kv.OsRelease["ID"]
if !ok {
return nil, fmt.Errorf("failed to collect os-release ID")
}
version, ok := kv.OsRelease["VERSION_ID"]
if !ok {
return nil, fmt.Errorf("failed to collect os-release VERSION_ID")
}
// HACK: fix mapping of version for oracle-linux and amazon linux 2018
switch {
case distribution == "ol" && strings.HasPrefix(version, "7."):
version = "7"
case distribution == "amzn" && strings.HasPrefix(version, "2018."):
version = "2018"
}
arch, ok := archMapping[runtime.GOARCH]
if !ok {
return nil, fmt.Errorf("failed to map runtime arch to btf arch")
}
return &kernelInfos{
distribution: distribution,
distribVersion: version,
arch: arch,
unameRelease: kv.UnameRelease,
}, nil
}
// BTFHubConstants represents all the information required for identifying
// a unique btf file from BTFHub
type BTFHubConstants struct {
Commit string `json:"commit"`
Constants []map[string]uint64 `json:"constants"`
Kernels []BTFHubKernel `json:"kernels"`
}
// BTFHubKernel represents all the information required for identifying
// a unique btf file from BTFHub
type BTFHubKernel struct {
Distribution string `json:"distrib"`
DistribVersion string `json:"version"`
Arch string `json:"arch"`
UnameRelease string `json:"uname_release"`
ConstantsIndex int `json:"cindex"`
}