aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/ast/ast.go2
-rw-r--r--pkg/compiler/check.go38
-rw-r--r--pkg/compiler/consts.go13
-rw-r--r--pkg/declextract/declextract.go15
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() {