diff options
Diffstat (limited to 'pkg')
| -rw-r--r-- | pkg/ast/ast.go | 2 | ||||
| -rw-r--r-- | pkg/compiler/check.go | 38 | ||||
| -rw-r--r-- | pkg/compiler/consts.go | 13 | ||||
| -rw-r--r-- | pkg/declextract/declextract.go | 15 |
4 files changed, 59 insertions, 9 deletions
diff --git a/pkg/ast/ast.go b/pkg/ast/ast.go index bd2d97c23..7c1db28ea 100644 --- a/pkg/ast/ast.go +++ b/pkg/ast/ast.go @@ -71,7 +71,7 @@ type Include struct { } func (n *Include) Info() (Pos, string, string) { - return n.Pos, tok2str[tokInclude], "" + return n.Pos, tok2str[tokInclude], n.File.Value } type Incdir struct { diff --git a/pkg/compiler/check.go b/pkg/compiler/check.go index 92e3e5e03..fbf84857d 100644 --- a/pkg/compiler/check.go +++ b/pkg/compiler/check.go @@ -676,6 +676,44 @@ func CollectUnused(desc *ast.Description, target *targets.Target, eh ast.ErrorHa return nodes, nil } +// CollectUnusedConsts returns unused defines/includes. This is used only for auto-generated descriptions. +func CollectUnusedConsts(desc *ast.Description, target *targets.Target, includeUse map[string]string, + eh ast.ErrorHandler) ([]ast.Node, error) { + comp := createCompiler(desc, target, eh) + comp.typecheck() + if comp.errors > 0 { + return nil, errors.New("typecheck failed") + } + + var unused []ast.Node + for file, info := range comp.extractConsts() { + if !comp.fileMeta(ast.Pos{File: file}).Automatic { + continue + } + usedDefines := make(map[string]bool) + usedIncludes := make(map[string]bool) + for _, c := range info.Consts { + if c.Used { + usedDefines[c.Name] = true + usedIncludes[includeUse[c.Name]] = true + } + } + for _, decl := range comp.desc.Nodes { + switch n := decl.(type) { + case *ast.Define: + if n.Pos.File == file && !usedDefines[n.Name.Name] { + unused = append(unused, n) + } + case *ast.Include: + if n.Pos.File == file && !usedIncludes[n.File.Value] { + unused = append(unused, n) + } + } + } + } + return unused, nil +} + func (comp *compiler) collectUnused() []ast.Node { var unused []ast.Node diff --git a/pkg/compiler/consts.go b/pkg/compiler/consts.go index bcbd40e52..6ce3f81f1 100644 --- a/pkg/compiler/consts.go +++ b/pkg/compiler/consts.go @@ -23,6 +23,7 @@ type ConstInfo struct { type Const struct { Name string Pos ast.Pos + Used bool // otherwise only defined } func ExtractConsts(desc *ast.Description, target *targets.Target, eh ast.ErrorHandler) map[string]*ConstInfo { @@ -86,7 +87,7 @@ func (comp *compiler) extractConsts() map[string]*ConstInfo { comp.error(pos, "redefining builtin const %v", name) } info.defines[name] = v - comp.addConst(ctx, pos, name) + ctx.addConst(pos, name, false) case *ast.Call: if comp.target.HasCallNumber(n.CallName) { comp.addConst(ctx, pos, comp.target.SyscallPrefix+n.CallName) @@ -178,10 +179,10 @@ func (comp *compiler) addConst(ctx *constContext, pos ast.Pos, name string) { if _, isFlag := comp.intFlags[name]; isFlag { return } - ctx.addConst(pos, name) + ctx.addConst(pos, name, true) for _, instantions := range ctx.instantionStack { for _, pos1 := range instantions { - ctx.addConst(pos1, name) + ctx.addConst(pos1, name, true) } } } @@ -193,11 +194,15 @@ type constInfo struct { incdirArray []string } -func (ctx *constContext) addConst(pos ast.Pos, name string) { +func (ctx *constContext) addConst(pos ast.Pos, name string, used bool) { info := ctx.getConstInfo(pos) + if c := info.consts[name]; c != nil && c.Used { + used = true + } info.consts[name] = &Const{ Pos: pos, Name: name, + Used: used, } } diff --git a/pkg/declextract/declextract.go b/pkg/declextract/declextract.go index fdf06b373..9df449b63 100644 --- a/pkg/declextract/declextract.go +++ b/pkg/declextract/declextract.go @@ -16,7 +16,7 @@ import ( ) func Run(out *Output, probe *ifaceprobe.Info, syscallRename map[string][]string, trace io.Writer) ( - []byte, []*Interface, error) { + []byte, []*Interface, map[string]string, error) { ctx := &context{ Output: out, probe: probe, @@ -29,7 +29,7 @@ func Run(out *Output, probe *ifaceprobe.Info, syscallRename map[string][]string, } ctx.processFunctions() ctx.processTypingFacts() - ctx.processConsts() + includeUse := ctx.processConsts() ctx.processEnums() ctx.processStructs() ctx.processSyscalls() @@ -37,7 +37,7 @@ func Run(out *Output, probe *ifaceprobe.Info, syscallRename map[string][]string, ctx.serialize() ctx.finishInterfaces() - return ctx.descriptions.Bytes(), ctx.interfaces, errors.Join(ctx.errs...) + return ctx.descriptions.Bytes(), ctx.interfaces, includeUse, errors.Join(ctx.errs...) } type context struct { @@ -75,7 +75,7 @@ func (ctx *context) trace(msg string, args ...any) { } } -func (ctx *context) processConsts() { +func (ctx *context) processConsts() map[string]string { replaces := map[string]string{ // Arches may use some includes from asm-generic and some from arch/arm. // If the arch used for extract used asm-generic for a header, @@ -85,6 +85,7 @@ func (ctx *context) processConsts() { "include/uapi/asm-generic/sockios.h": "asm/sockios.h", } defineDedup := make(map[string]bool) + includeUse := make(map[string]string) for _, ci := range ctx.Consts { if strings.Contains(ci.Filename, "/uapi/") && !strings.Contains(ci.Filename, "arch/x86/") && strings.HasSuffix(ci.Filename, ".h") { @@ -93,6 +94,7 @@ func (ctx *context) processConsts() { filename = replace } ctx.includes = append(ctx.includes, filename) + includeUse[ci.Name] = filename continue } // Remove duplicate defines (even with different values). Unfortunately we get few of these. @@ -118,6 +120,11 @@ func (ctx *context) processConsts() { "linux/types.h", "net/netlink.h", }, ctx.includes...) + // Also pretend they are used. + includeUse["__NR_read"] = "vdso/bits.h" + includeUse["__NR_write"] = "linux/types.h" + includeUse["__NR_close"] = "net/netlink.h" + return includeUse } func (ctx *context) processEnums() { |
