Skip to content

Commit

Permalink
Move all code over and update imports
Browse files Browse the repository at this point in the history
Signed-off-by: grantseltzer <grantseltzer@gmail.com>
  • Loading branch information
grantseltzer committed Jun 27, 2024
1 parent c785fa4 commit 0125555
Show file tree
Hide file tree
Showing 49 changed files with 172,279 additions and 10 deletions.
6 changes: 3 additions & 3 deletions cmd/system-probe/modules/dynamic_instrumentation.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
sysconfigtypes "github.com/DataDog/datadog-agent/cmd/system-probe/config/types"
"github.com/DataDog/datadog-agent/comp/core/telemetry"
workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def"
"github.com/DataDog/datadog-agent/pkg/dynamicinstrumentation"
"github.com/DataDog/datadog-agent/pkg/di/module"
"github.com/DataDog/datadog-agent/pkg/ebpf"
"github.com/DataDog/datadog-agent/pkg/util/optional"
)
Expand All @@ -26,12 +26,12 @@ var DynamicInstrumentation = module.Factory{
Name: config.DynamicInstrumentationModule,
ConfigNamespaces: []string{},
Fn: func(agentConfiguration *sysconfigtypes.Config, _ optional.Option[workloadmeta.Component], _ telemetry.Component) (module.Module, error) {
config, err := dynamicinstrumentation.NewConfig(agentConfiguration)
config, err := module.NewConfig(agentConfiguration)
if err != nil {
return nil, fmt.Errorf("invalid dynamic instrumentation module configuration: %w", err)
}

m, err := dynamicinstrumentation.NewModule(config)
m, err := module.NewModule(config)
if errors.Is(err, ebpf.ErrNotImplemented) {
return nil, module.ErrNotEnabled
}
Expand Down
139 changes: 139 additions & 0 deletions pkg/di/codegen/codegen.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package codegen

import (
"bytes"
"errors"
"fmt"
"log"
"reflect"
"strings"
"text/template"

"github.com/DataDog/datadog-agent/pkg/di/ditypes"
)

type BPFProgram struct {
ProgramText string

// Used for bpf code generation
Probe *ditypes.Probe
PopulatedParameterText string
}

// GenerateBPFProgram generates the source code associated with the probe and data
// in it's associated proccess info.
func GenerateBPFProgram(procInfo *ditypes.ProcessInfo, probe *ditypes.Probe) error {

prog := &BPFProgram{
Probe: probe,
}

programTemplate, err := template.New("program_template").Parse(programTemplateText)
if err != nil {
return err
}

flattenedParams := flattenParameters(procInfo.TypeMap.Functions[probe.FuncName])
parametersText, err := generateParameterText(flattenedParams)
if err != nil {
return err
}

prog.PopulatedParameterText = parametersText

buf := new(bytes.Buffer)
err = programTemplate.Execute(buf, prog)
if err != nil {
return err
}

log.Println(buf.String())
probe.InstrumentationInfo.BPFSourceCode = buf.String()

return nil
}

func generateParameterText(paramPieces []ditypes.Parameter) (string, error) {
var executedTemplateBytes []byte
for i := range paramPieces {
buf := new(bytes.Buffer)

template, err := resolveParameterTemplate(paramPieces[i])
if err != nil {
return "", err
}
paramPieces[i].Type = cleanupTypeName(paramPieces[i].Type)
err = template.Execute(buf, paramPieces[i])
if err != nil {
return "", fmt.Errorf("could not execute template for generating read of parameter: %w", err)
}
executedTemplateBytes = append(executedTemplateBytes, buf.Bytes()...)
}
return string(executedTemplateBytes), nil
}

func resolveParameterTemplate(param ditypes.Parameter) (*template.Template, error) {
if param.Location.InReg {
return resolveRegisterParameterTemplate(param)
} else {
return resolveStackParameterTemplate(param)
}
}

func resolveRegisterParameterTemplate(param ditypes.Parameter) (*template.Template, error) {
needsDereference := param.Location.NeedsDereference
stringType := param.Kind == uint(reflect.String)
sliceType := param.Kind == uint(reflect.Slice)

if needsDereference && stringType {
// Register String Pointer
return template.New("string_register_pointer_template").Parse(stringPointerRegisterTemplateText)
} else if needsDereference && sliceType {
// Register Slice Pointer
return template.New("slice_register_pointer_template").Parse(slicePointerRegisterTemplateText)
} else if needsDereference {
// Register Pointer
return template.New("pointer_register_template").Parse(pointerRegisterTemplateText)
} else if stringType {
// Register String
return template.New("string_register_template").Parse(stringRegisterTemplateText)
} else if sliceType {
// Register Slice
return template.New("slice_register_template").Parse(sliceRegisterTemplateText)
} else if !needsDereference {
// Register Normal Value
return template.New("register_template").Parse(normalValueRegisterTemplateText)
}
return nil, errors.New("no template created: invalid or unsupported type")
}

func resolveStackParameterTemplate(param ditypes.Parameter) (*template.Template, error) {
needsDereference := param.Location.NeedsDereference
stringType := param.Kind == uint(reflect.String)
sliceType := param.Kind == uint(reflect.Slice)

if needsDereference && stringType {
// Stack String Pointer
return template.New("string_stack_pointer_template").Parse(stringPointerStackTemplateText)
} else if needsDereference && sliceType {
// Stack Slice Pointer
return template.New("slice_stack_pointer_template").Parse(slicePointerStackTemplateText)
} else if needsDereference {
// Stack Pointer
return template.New("pointer_stack_template").Parse(pointerStackTemplateText)
} else if stringType {
// Stack String
return template.New("string_stack_template").Parse(stringStackTemplateText)
} else if sliceType {
// Stack Slice
return template.New("slice_stack_template").Parse(sliceStackTemplateText)
} else if !needsDereference {
// Stack Normal Value
return template.New("stack_template").Parse(normalValueStackTemplateText)
}
return nil, errors.New("no template created: invalid or unsupported type")
}

func cleanupTypeName(s string) string {
return strings.TrimPrefix(s, "*")
}
47 changes: 47 additions & 0 deletions pkg/di/codegen/output_offsets.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package codegen

import (
"math/rand"
"reflect"

"github.com/DataDog/datadog-agent/pkg/di/ditypes"
)

func flattenParameters(params []ditypes.Parameter) []ditypes.Parameter {
flattenedParams := []ditypes.Parameter{}
for i := range params {
kind := reflect.Kind(params[i].Kind)
if hasHeader(kind) {
paramHeader := params[i]
paramHeader.ParameterPieces = nil
flattenedParams = append(flattenedParams, paramHeader)
flattenedParams = append(flattenedParams, flattenParameters(params[i].ParameterPieces)...)
} else if len(params[i].ParameterPieces) > 0 {
flattenedParams = append(flattenedParams, flattenParameters(params[i].ParameterPieces)...)
} else {
flattenedParams = append(flattenedParams, params[i])
}
}

for i := range flattenedParams {
flattenedParams[i].ID = randomID()
}

return flattenedParams
}

func hasHeader(kind reflect.Kind) bool {
return kind == reflect.Struct ||
kind == reflect.Slice ||
kind == reflect.Array ||
kind == reflect.Pointer
}

func randomID() string {
length := 6
ran_str := make([]byte, length)
for i := 0; i < length; i++ {
ran_str[i] = byte(65 + rand.Intn(25))
}
return string(ran_str)
}
Loading

0 comments on commit 0125555

Please sign in to comment.