2018-05-17 20:17:01 +02:00
|
|
|
// Copyright (C) 2018 The Android Open Source Project
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
package bpf
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"io"
|
2022-07-07 11:48:06 +02:00
|
|
|
"path/filepath"
|
2018-05-17 20:17:01 +02:00
|
|
|
"strings"
|
|
|
|
|
|
|
|
"android/soong/android"
|
|
|
|
|
|
|
|
"github.com/google/blueprint"
|
2021-12-03 05:09:45 +01:00
|
|
|
"github.com/google/blueprint/proptools"
|
2018-05-17 20:17:01 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
func init() {
|
2021-02-24 19:51:54 +01:00
|
|
|
registerBpfBuildComponents(android.InitRegistrationContext)
|
2018-05-17 20:17:01 +02:00
|
|
|
pctx.Import("android/soong/cc/config")
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
pctx = android.NewPackageContext("android/soong/bpf")
|
|
|
|
|
2020-01-27 20:19:44 +01:00
|
|
|
ccRule = pctx.AndroidRemoteStaticRule("ccRule", android.RemoteRuleSupports{Goma: true},
|
2018-05-17 20:17:01 +02:00
|
|
|
blueprint.RuleParams{
|
|
|
|
Depfile: "${out}.d",
|
|
|
|
Deps: blueprint.DepsGCC,
|
|
|
|
Command: "$ccCmd --target=bpf -c $cFlags -MD -MF ${out}.d -o $out $in",
|
|
|
|
CommandDeps: []string{"$ccCmd"},
|
|
|
|
},
|
|
|
|
"ccCmd", "cFlags")
|
2021-12-03 05:09:45 +01:00
|
|
|
|
|
|
|
stripRule = pctx.AndroidStaticRule("stripRule",
|
|
|
|
blueprint.RuleParams{
|
|
|
|
Command: `$stripCmd --strip-unneeded --remove-section=.rel.BTF ` +
|
|
|
|
`--remove-section=.rel.BTF.ext --remove-section=.BTF.ext $in -o $out`,
|
|
|
|
CommandDeps: []string{"$stripCmd"},
|
|
|
|
},
|
|
|
|
"stripCmd")
|
2018-05-17 20:17:01 +02:00
|
|
|
)
|
|
|
|
|
2021-02-24 19:51:54 +01:00
|
|
|
func registerBpfBuildComponents(ctx android.RegistrationContext) {
|
|
|
|
ctx.RegisterModuleType("bpf", BpfFactory)
|
|
|
|
}
|
|
|
|
|
|
|
|
var PrepareForTestWithBpf = android.FixtureRegisterWithContext(registerBpfBuildComponents)
|
|
|
|
|
2020-09-02 10:23:38 +02:00
|
|
|
// BpfModule interface is used by the apex package to gather information from a bpf module.
|
|
|
|
type BpfModule interface {
|
|
|
|
android.Module
|
|
|
|
|
|
|
|
OutputFiles(tag string) (android.Paths, error)
|
2021-11-10 15:02:57 +01:00
|
|
|
|
|
|
|
// Returns the sub install directory if the bpf module is included by apex.
|
|
|
|
SubDir() string
|
2020-09-02 10:23:38 +02:00
|
|
|
}
|
|
|
|
|
2018-05-17 20:17:01 +02:00
|
|
|
type BpfProperties struct {
|
2019-03-05 07:35:41 +01:00
|
|
|
Srcs []string `android:"path"`
|
2018-05-17 20:17:01 +02:00
|
|
|
Cflags []string
|
|
|
|
Include_dirs []string
|
2021-11-10 15:02:57 +01:00
|
|
|
Sub_dir string
|
2021-12-03 05:09:45 +01:00
|
|
|
// If set to true, generate BTF debug info for maps & programs
|
2019-12-12 23:23:42 +01:00
|
|
|
Btf *bool
|
|
|
|
Vendor *bool
|
|
|
|
|
|
|
|
VendorInternal bool `blueprint:"mutated"`
|
2018-05-17 20:17:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
type bpf struct {
|
|
|
|
android.ModuleBase
|
|
|
|
|
|
|
|
properties BpfProperties
|
|
|
|
|
|
|
|
objs android.Paths
|
|
|
|
}
|
|
|
|
|
2019-12-12 23:23:42 +01:00
|
|
|
var _ android.ImageInterface = (*bpf)(nil)
|
|
|
|
|
|
|
|
func (bpf *bpf) ImageMutatorBegin(ctx android.BaseModuleContext) {}
|
|
|
|
|
|
|
|
func (bpf *bpf) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
|
|
|
|
return !proptools.Bool(bpf.properties.Vendor)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bpf *bpf) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bpf *bpf) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bpf *bpf) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bpf *bpf) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bpf *bpf) ExtraImageVariations(ctx android.BaseModuleContext) []string {
|
|
|
|
if proptools.Bool(bpf.properties.Vendor) {
|
|
|
|
return []string{"vendor"}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bpf *bpf) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) {
|
|
|
|
bpf.properties.VendorInternal = variation == "vendor"
|
|
|
|
}
|
|
|
|
|
2018-05-17 20:17:01 +02:00
|
|
|
func (bpf *bpf) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|
|
|
cflags := []string{
|
|
|
|
"-nostdlibinc",
|
2020-03-25 23:01:27 +01:00
|
|
|
|
|
|
|
// Make paths in deps files relative
|
|
|
|
"-no-canonical-prefixes",
|
|
|
|
|
2018-05-17 20:17:01 +02:00
|
|
|
"-O2",
|
|
|
|
"-isystem bionic/libc/include",
|
|
|
|
"-isystem bionic/libc/kernel/uapi",
|
|
|
|
// The architecture doesn't matter here, but asm/types.h is included by linux/types.h.
|
|
|
|
"-isystem bionic/libc/kernel/uapi/asm-arm64",
|
|
|
|
"-isystem bionic/libc/kernel/android/uapi",
|
2021-12-20 11:22:55 +01:00
|
|
|
"-I frameworks/libs/net/common/native/bpf_headers/include/bpf",
|
2020-02-19 00:38:36 +01:00
|
|
|
// TODO(b/149785767): only give access to specific file with AID_* constants
|
|
|
|
"-I system/core/libcutils/include",
|
2018-05-17 20:17:01 +02:00
|
|
|
"-I " + ctx.ModuleDir(),
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, dir := range android.PathsForSource(ctx, bpf.properties.Include_dirs) {
|
|
|
|
cflags = append(cflags, "-I "+dir.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
cflags = append(cflags, bpf.properties.Cflags...)
|
|
|
|
|
2021-12-03 05:09:45 +01:00
|
|
|
if proptools.Bool(bpf.properties.Btf) {
|
|
|
|
cflags = append(cflags, "-g")
|
|
|
|
}
|
|
|
|
|
2019-03-06 07:25:09 +01:00
|
|
|
srcs := android.PathsForModuleSrc(ctx, bpf.properties.Srcs)
|
2018-05-17 20:17:01 +02:00
|
|
|
|
|
|
|
for _, src := range srcs {
|
2022-07-07 11:48:06 +02:00
|
|
|
if strings.ContainsRune(filepath.Base(src.String()), '_') {
|
|
|
|
ctx.ModuleErrorf("invalid character '_' in source name")
|
|
|
|
}
|
2021-12-03 05:09:45 +01:00
|
|
|
obj := android.ObjPathWithExt(ctx, "unstripped", src, "o")
|
2018-05-17 20:17:01 +02:00
|
|
|
|
|
|
|
ctx.Build(pctx, android.BuildParams{
|
2019-05-15 01:05:20 +02:00
|
|
|
Rule: ccRule,
|
2018-05-17 20:17:01 +02:00
|
|
|
Input: src,
|
|
|
|
Output: obj,
|
|
|
|
Args: map[string]string{
|
|
|
|
"cFlags": strings.Join(cflags, " "),
|
|
|
|
"ccCmd": "${config.ClangBin}/clang",
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
2021-12-03 05:09:45 +01:00
|
|
|
if proptools.Bool(bpf.properties.Btf) {
|
|
|
|
objStripped := android.ObjPathWithExt(ctx, "", src, "o")
|
|
|
|
ctx.Build(pctx, android.BuildParams{
|
2019-12-12 23:23:42 +01:00
|
|
|
Rule: stripRule,
|
|
|
|
Input: obj,
|
2021-12-03 05:09:45 +01:00
|
|
|
Output: objStripped,
|
|
|
|
Args: map[string]string{
|
|
|
|
"stripCmd": "${config.ClangBin}/llvm-strip",
|
|
|
|
},
|
|
|
|
})
|
|
|
|
bpf.objs = append(bpf.objs, objStripped.WithoutRel())
|
|
|
|
} else {
|
|
|
|
bpf.objs = append(bpf.objs, obj.WithoutRel())
|
|
|
|
}
|
|
|
|
|
2018-05-17 20:17:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bpf *bpf) AndroidMk() android.AndroidMkData {
|
|
|
|
return android.AndroidMkData{
|
|
|
|
Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
|
|
|
|
var names []string
|
|
|
|
fmt.Fprintln(w)
|
|
|
|
fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
|
|
|
|
fmt.Fprintln(w)
|
2019-12-12 23:23:42 +01:00
|
|
|
var localModulePath string
|
|
|
|
if bpf.properties.VendorInternal {
|
|
|
|
localModulePath = "LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)/bpf"
|
|
|
|
} else {
|
|
|
|
localModulePath = "LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/bpf"
|
|
|
|
}
|
2021-11-10 15:02:57 +01:00
|
|
|
if len(bpf.properties.Sub_dir) > 0 {
|
|
|
|
localModulePath += "/" + bpf.properties.Sub_dir
|
|
|
|
}
|
2018-05-17 20:17:01 +02:00
|
|
|
for _, obj := range bpf.objs {
|
|
|
|
objName := name + "_" + obj.Base()
|
|
|
|
names = append(names, objName)
|
|
|
|
fmt.Fprintln(w, "include $(CLEAR_VARS)")
|
|
|
|
fmt.Fprintln(w, "LOCAL_MODULE := ", objName)
|
2021-01-07 04:34:31 +01:00
|
|
|
data.Entries.WriteLicenseVariables(w)
|
2018-05-17 20:17:01 +02:00
|
|
|
fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", obj.String())
|
|
|
|
fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", obj.Base())
|
|
|
|
fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC")
|
2021-11-10 15:02:57 +01:00
|
|
|
fmt.Fprintln(w, localModulePath)
|
2018-05-17 20:17:01 +02:00
|
|
|
fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
|
|
|
|
fmt.Fprintln(w)
|
|
|
|
}
|
|
|
|
fmt.Fprintln(w, "include $(CLEAR_VARS)")
|
|
|
|
fmt.Fprintln(w, "LOCAL_MODULE := ", name)
|
2021-01-07 04:34:31 +01:00
|
|
|
data.Entries.WriteLicenseVariables(w)
|
2018-05-17 20:17:01 +02:00
|
|
|
fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES :=", strings.Join(names, " "))
|
|
|
|
fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-29 23:40:35 +02:00
|
|
|
// Implements OutputFileFileProducer interface so that the obj output can be used in the data property
|
2018-12-14 00:01:46 +01:00
|
|
|
// of other modules.
|
2019-05-29 23:40:35 +02:00
|
|
|
func (bpf *bpf) OutputFiles(tag string) (android.Paths, error) {
|
|
|
|
switch tag {
|
|
|
|
case "":
|
|
|
|
return bpf.objs, nil
|
|
|
|
default:
|
|
|
|
return nil, fmt.Errorf("unsupported module reference tag %q", tag)
|
|
|
|
}
|
2018-12-14 00:01:46 +01:00
|
|
|
}
|
|
|
|
|
2021-11-10 15:02:57 +01:00
|
|
|
func (bpf *bpf) SubDir() string {
|
|
|
|
return bpf.properties.Sub_dir
|
|
|
|
}
|
|
|
|
|
2019-05-29 23:40:35 +02:00
|
|
|
var _ android.OutputFileProducer = (*bpf)(nil)
|
2018-12-14 00:01:46 +01:00
|
|
|
|
2020-09-02 10:23:38 +02:00
|
|
|
func BpfFactory() android.Module {
|
2018-05-17 20:17:01 +02:00
|
|
|
module := &bpf{}
|
|
|
|
|
|
|
|
module.AddProperties(&module.properties)
|
|
|
|
|
|
|
|
android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
|
|
|
|
return module
|
|
|
|
}
|