Repository: cilium/ebpf
Pull request #593 (2022-03-09 08:55:01)

btf: rename 'Core' to 'CORE'
CO-RE/CORE is an acronym, consistently name it that way.

Missing program BTF should not be silently ignored in `collectCORERelos()`, so make it return error.


Patch:
diff --git a/internal/btf/btf.go b/internal/btf/btf.go
index 86eec0a..899ee89 100644
--- a/internal/btf/btf.go
+++ b/internal/btf/btf.go
@@ -46,7 +46,7 @@ type Spec struct {
 	// Data from .BTF.ext. indexed by function name.
 	funcInfos map[string]FuncInfo
 	lineInfos map[string]LineInfos
-	coreRelos map[string]CoreRelos
+	coreRelos map[string]CORERelos
 
 	byteOrder binary.ByteOrder
 }
@@ -190,13 +190,13 @@ func loadSpecFromELF(file *internal.SafeELFFile) (*Spec, error) {
 	return spec, nil
 }
 
-// splitExtInfos takes FuncInfos, LineInfos and CoreRelos indexed by section and
+// splitExtInfos takes FuncInfos, LineInfos and CORERelos indexed by section and
 // transforms them to be indexed by function. Retrieves function names from
 // the BTF spec.
 func (spec *Spec) splitExtInfos(info *extInfo) error {
 	ofi := make(map[string]FuncInfo)
 	oli := make(map[string]LineInfos)
-	ocr := make(map[string]CoreRelos)
+	ocr := make(map[string]CORERelos)
 
 	for secName, secFuncInfos := range info.funcInfos {
 		// Collect functions from each section and organize them by name.
@@ -835,7 +835,7 @@ type Program struct {
 	spec      *Spec
 	FuncInfo  FuncInfo
 	LineInfos LineInfos
-	CoreRelos CoreRelos
+	CORERelos CORERelos
 }
 
 // Spec returns the BTF spec of this program.
@@ -846,7 +846,7 @@ func (p *Program) Spec() *Spec {
 // CORERelocate returns the changes required to adjust the program to the target.
 //
 // Passing a nil target will relocate against the running kernel.
-func CORERelocate(local, target *Spec, relos CoreRelos) (COREFixups, error) {
+func CORERelocate(local, target *Spec, relos CORERelos) (COREFixups, error) {
 	if len(relos) == 0 {
 		return nil, nil
 	}
diff --git a/internal/btf/core.go b/internal/btf/core.go
index 9590830..317e7c3 100644
--- a/internal/btf/core.go
+++ b/internal/btf/core.go
@@ -191,13 +191,13 @@ func (k COREKind) checksForExistence() bool {
 	return k == reloEnumvalExists || k == reloTypeExists || k == reloFieldExists
 }
 
-func coreRelocate(local, target *Spec, relos CoreRelos) (COREFixups, error) {
+func coreRelocate(local, target *Spec, relos CORERelos) (COREFixups, error) {
 	if local.byteOrder != target.byteOrder {
 		return nil, fmt.Errorf("can't relocate %s against %s", local.byteOrder, target.byteOrder)
 	}
 
 	var ids []TypeID
-	relosByID := make(map[TypeID]CoreRelos)
+	relosByID := make(map[TypeID]CORERelos)
 	result := make(COREFixups, len(relos))
 	for _, relo := range relos {
 		if relo.kind == reloTypeIDLocal {
@@ -262,7 +262,7 @@ var errImpossibleRelocation = errors.New("impossible relocation")
 //
 // The best target is determined by scoring: the less poisoning we have to do
 // the better the target is.
-func coreCalculateFixups(local Type, targets []Type, relos CoreRelos) ([]COREFixup, error) {
+func coreCalculateFixups(local Type, targets []Type, relos CORERelos) ([]COREFixup, error) {
 	localID := local.ID()
 	local, err := copyType(local, skipQualifiersAndTypedefs)
 	if err != nil {
@@ -326,7 +326,7 @@ func coreCalculateFixups(local Type, targets []Type, relos CoreRelos) ([]COREFix
 
 // coreCalculateFixup calculates the fixup for a single local type, target type
 // and relocation.
-func coreCalculateFixup(local Type, localID TypeID, target Type, targetID TypeID, relo CoreRelo) (COREFixup, error) {
+func coreCalculateFixup(local Type, localID TypeID, target Type, targetID TypeID, relo CORERelocation) (COREFixup, error) {
 	fixup := func(local, target uint32) (COREFixup, error) {
 		return COREFixup{relo.kind, local, target, false}, nil
 	}
@@ -462,7 +462,7 @@ func coreCalculateFixup(local Type, localID TypeID, target Type, targetID TypeID
  */
 type coreAccessor []int
 
-func parseCoreAccessor(accessor string) (coreAccessor, error) {
+func parseCOREAccessor(accessor string) (coreAccessor, error) {
 	if accessor == "" {
 		return nil, fmt.Errorf("empty accessor")
 	}
diff --git a/internal/btf/ext_info.go b/internal/btf/ext_info.go
index 6342d19..be614e7 100644
--- a/internal/btf/ext_info.go
+++ b/internal/btf/ext_info.go
@@ -17,7 +17,7 @@ import (
 type extInfo struct {
 	funcInfos map[string][]bpfFuncInfo
 	lineInfos map[string][]bpfLineInfo
-	relos     map[string]CoreRelos
+	relos     map[string]CORERelos
 }
 
 // loadExtInfos parses the .BTF.ext section into its constituent parts.
@@ -30,7 +30,7 @@ func loadExtInfos(r io.ReaderAt, bo binary.ByteOrder, strings stringTable) (*ext
 		return nil, fmt.Errorf("parsing BTF extension header: %w", err)
 	}
 
-	coreHeader, err := parseBTFExtCoreHeader(headerRd, bo, extHeader)
+	coreHeader, err := parseBTFExtCOREHeader(headerRd, bo, extHeader)
 	if err != nil {
 		return nil, fmt.Errorf("parsing BTF CO-RE header: %w", err)
 	}
@@ -47,10 +47,10 @@ func loadExtInfos(r io.ReaderAt, bo binary.ByteOrder, strings stringTable) (*ext
 		return nil, fmt.Errorf("parsing BTF line info: %w", err)
 	}
 
-	relos := make(map[string]CoreRelos)
-	if coreHeader != nil && coreHeader.CoreReloOff > 0 && coreHeader.CoreReloLen > 0 {
-		buf = internal.NewBufferedSectionReader(r, extHeader.coreReloStart(coreHeader), int64(coreHeader.CoreReloLen))
-		relos, err = parseCoreRelos(buf, bo, strings)
+	relos := make(map[string]CORERelos)
+	if coreHeader != nil && coreHeader.COREReloOff > 0 && coreHeader.COREReloLen > 0 {
+		buf = internal.NewBufferedSectionReader(r, extHeader.coreReloStart(coreHeader), int64(coreHeader.COREReloLen))
+		relos, err = parseCORERelos(buf, bo, strings)
 		if err != nil {
 			return nil, fmt.Errorf("parsing CO-RE relocation info: %w", err)
 		}
@@ -66,7 +66,7 @@ type btfExtHeader struct {
 	Flags   uint8
 
 	// HdrLen is larger than the size of struct btfExtHeader when it is
-	// immediately followed by a btfExtCoreHeader.
+	// immediately followed by a btfExtCOREHeader.
 	HdrLen uint32
 
 	FuncInfoOff uint32
@@ -115,21 +115,21 @@ func (h *btfExtHeader) lineInfoStart() int64 {
 
 // coreReloStart returns the offset from the beginning of the .BTF.ext section
 // to the start of its CO-RE relocation entries.
-func (h *btfExtHeader) coreReloStart(ch *btfExtCoreHeader) int64 {
-	return int64(h.HdrLen + ch.CoreReloOff)
+func (h *btfExtHeader) coreReloStart(ch *btfExtCOREHeader) int64 {
+	return int64(h.HdrLen + ch.COREReloOff)
 }
 
-// btfExtCoreHeader is found right after the btfExtHeader when its HdrLen
+// btfExtCOREHeader is found right after the btfExtHeader when its HdrLen
 // field is larger than its size.
-type btfExtCoreHeader struct {
-	CoreReloOff uint32
-	CoreReloLen uint32
+type btfExtCOREHeader struct {
+	COREReloOff uint32
+	COREReloLen uint32
 }
 
-// parseBTFExtCoreHeader parses the tail of the .BTF.ext header. If additional
+// parseBTFExtCOREHeader parses the tail of the .BTF.ext header. If additional
 // header bytes are present, extHeader.HdrLen will be larger than the struct,
 // indicating the presence of a CO-RE extension header.
-func parseBTFExtCoreHeader(r io.Reader, bo binary.ByteOrder, extHeader *btfExtHeader) (*btfExtCoreHeader, error) {
+func parseBTFExtCOREHeader(r io.Reader, bo binary.ByteOrder, extHeader *btfExtHeader) (*btfExtCOREHeader, error) {
 	extHdrSize := int64(binary.Size(&extHeader))
 	remainder := int64(extHeader.HdrLen) - extHdrSize
 
@@ -137,7 +137,7 @@ func parseBTFExtCoreHeader(r io.Reader, bo binary.ByteOrder, extHeader *btfExtHe
 		return nil, nil
 	}
 
-	var coreHeader btfExtCoreHeader
+	var coreHeader btfExtCOREHeader
 	if err := binary.Read(r, bo, &coreHeader); err != nil {
 		return nil, fmt.Errorf("can't read header: %v", err)
 	}
@@ -430,27 +430,27 @@ func parseLineInfoRecords(r io.Reader, bo binary.ByteOrder, recordSize uint32, r
 	return out, nil
 }
 
-// bpfCoreRelo matches the kernel's struct bpf_core_relo.
-type bpfCoreRelo struct {
+// bpfCORERelo matches the kernel's struct bpf_core_relo.
+type bpfCORERelo struct {
 	InsnOff      uint32
 	TypeID       TypeID
 	AccessStrOff uint32
 	Kind         COREKind
 }
 
-type CoreRelo struct {
+type CORERelocation struct {
 	insnOff  uint32
 	typeID   TypeID
 	accessor coreAccessor
 	kind     COREKind
 }
 
-type CoreRelos []CoreRelo
+type CORERelos []CORERelocation
 
-// Offset adds offset to the instruction offset of all CoreRelos
+// Offset adds offset to the instruction offset of all CORERelos
 // and returns the result.
-func (cr CoreRelos) Offset(offset uint32) CoreRelos {
-	var relos CoreRelos
+func (cr CORERelos) Offset(offset uint32) CORERelos {
+	var relos CORERelos
 	for _, relo := range cr {
 		relo.insnOff += offset
 		relos = append(relos, relo)
@@ -458,11 +458,11 @@ func (cr CoreRelos) Offset(offset uint32) CoreRelos {
 	return relos
 }
 
-var extInfoReloSize = binary.Size(bpfCoreRelo{})
+var extInfoReloSize = binary.Size(bpfCORERelo{})
 
-// parseCoreRelos parses a core_relos sub-section within .BTF.ext ito a map of
+// parseCORERelos parses a core_relos sub-section within .BTF.ext ito a map of
 // CO-RE relocations indexed by section name.
-func parseCoreRelos(r io.Reader, bo binary.ByteOrder, strings stringTable) (map[string]CoreRelos, error) {
+func parseCORERelos(r io.Reader, bo binary.ByteOrder, strings stringTable) (map[string]CORERelos, error) {
 	recordSize, err := parseExtInfoRecordSize(r, bo)
 	if err != nil {
 		return nil, err
@@ -472,7 +472,7 @@ func parseCoreRelos(r io.Reader, bo binary.ByteOrder, strings stringTable) (map[
 		return nil, fmt.Errorf("expected record size %d, got %d", extInfoReloSize, recordSize)
 	}
 
-	result := make(map[string]CoreRelos)
+	result := make(map[string]CORERelos)
 	for {
 		secName, infoHeader, err := parseExtInfoSec(r, bo, strings)
 		if errors.Is(err, io.EOF) {
@@ -482,7 +482,7 @@ func parseCoreRelos(r io.Reader, bo binary.ByteOrder, strings stringTable) (map[
 			return nil, err
 		}
 
-		records, err := parseCoreReloRecords(r, bo, recordSize, infoHeader.NumInfo, strings)
+		records, err := parseCOREReloRecords(r, bo, recordSize, infoHeader.NumInfo, strings)
 		if err != nil {
 			return nil, fmt.Errorf("section %v: %w", secName, err)
 		}
@@ -491,13 +491,13 @@ func parseCoreRelos(r io.Reader, bo binary.ByteOrder, strings stringTable) (map[
 	}
 }
 
-// parseCoreReloRecords parses a stream of CO-RE relocation entries into a
+// parseCOREReloRecords parses a stream of CO-RE relocation entries into a
 // coreRelos. These records appear after a btf_ext_info_sec header in the
 // core_relos sub-section of .BTF.ext.
-func parseCoreReloRecords(r io.Reader, bo binary.ByteOrder, recordSize uint32, recordNum uint32, strings stringTable) (CoreRelos, error) {
-	var out CoreRelos
+func parseCOREReloRecords(r io.Reader, bo binary.ByteOrder, recordSize uint32, recordNum uint32, strings stringTable) (CORERelos, error) {
+	var out CORERelos
 
-	var relo bpfCoreRelo
+	var relo bpfCORERelo
 	for i := uint32(0); i < recordNum; i++ {
 		if err := binary.Read(r, bo, &relo); err != nil {
 			return nil, fmt.Errorf("can't read CO-RE relocation: %v", err)
@@ -512,12 +512,12 @@ func parseCoreReloRecords(r io.Reader, bo binary.ByteOrder, recordSize uint32, r
 			return nil, err
 		}
 
-		accessor, err := parseCoreAccessor(accessorStr)
+		accessor, err := parseCOREAccessor(accessorStr)
 		if err != nil {
 			return nil, fmt.Errorf("accessor %q: %s", accessorStr, err)
 		}
 
-		out = append(out, CoreRelo{
+		out = append(out, CORERelocation{
 			relo.InsnOff,
 			relo.TypeID,
 			accessor,
diff --git a/linker.go b/linker.go
index b40856b..78addb4 100644
--- a/linker.go
+++ b/linker.go
@@ -81,22 +81,18 @@ func findReferences(progs map[string]*ProgramSpec) error {
 	return nil
 }
 
-// collectCoreRelos returns a list of CO-RE relocations of the layout's progs
+// collectCORERelos returns a list of CO-RE relocations of the layout's progs
 // in order.
-func collectCoreRelos(layout []reference) btf.CoreRelos {
-	if len(layout) == 0 {
-		return nil
-	}
-
-	var relos btf.CoreRelos
+func collectCORERelos(layout []reference) (btf.CORERelos, error) {
+	var relos btf.CORERelos
 	for _, sym := range layout {
 		if sym.spec.BTF == nil {
-			continue
+			return nil, fmt.Errorf("program %s: missing BTF", sym.spec.Name)
 		}
-		relos = append(relos, sym.spec.BTF.CoreRelos.Offset(uint32(sym.offset))...)
+		relos = append(relos, sym.spec.BTF.CORERelos.Offset(uint32(sym.offset))...)
 	}
 
-	return relos
+	return relos, nil
 }
 
 // marshalFuncInfos returns the BTF func infos of all progs in order.
diff --git a/prog.go b/prog.go
index 47ca18e..5e990af 100644
--- a/prog.go
+++ b/prog.go
@@ -293,10 +293,13 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions, handles *hand
 	var btfDisabled bool
 	var core btf.COREFixups
 	if spec.BTF != nil {
-		relos := collectCoreRelos(layout)
+		relos, err := collectCORERelos(layout)
+		if err != nil {
+			return nil, fmt.Errorf("collecting CO-RE relocations: %w", err)
+		}
 		core, err = btf.CORERelocate(spec.BTF.Spec(), targetBTF, relos)
 		if err != nil {
-			return nil, fmt.Errorf("CO-RE relocations: %w", err)
+			return nil, fmt.Errorf("generating CO-RE fixups: %w", err)
 		}
 
 		handle, err := handles.btfHandle(spec.BTF.Spec())
@@ -328,7 +331,7 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions, handles *hand
 
 	insns, err := core.Apply(spec.Instructions)
 	if err != nil {
-		return nil, fmt.Errorf("CO-RE fixup: %w", err)
+		return nil, fmt.Errorf("applying CO-RE fixups: %w", err)
 	}
 
 	if err := fixupAndValidate(insns); err != nil {


Test patch:
diff --git a/internal/btf/core_reloc_test.go b/internal/btf/core_reloc_test.go
index d8c2b59..b254efc 100644
--- a/internal/btf/core_reloc_test.go
+++ b/internal/btf/core_reloc_test.go
@@ -12,7 +12,7 @@ import (
 	"github.com/cilium/ebpf/internal/testutils"
 )
 
-func TestCoreRelocationLoad(t *testing.T) {
+func TestCORERelocationLoad(t *testing.T) {
 	testutils.Files(t, testutils.Glob(t, "testdata/relocs-*.elf"), func(t *testing.T, file string) {
 		fh, err := os.Open(file)
 		if err != nil {
@@ -67,7 +67,7 @@ func TestCoreRelocationLoad(t *testing.T) {
 	})
 }
 
-func TestCoreRelocationRead(t *testing.T) {
+func TestCORERelocationRead(t *testing.T) {
 	testutils.Files(t, testutils.Glob(t, "testdata/relocs_read-*.elf"), func(t *testing.T, file string) {
 		fh, err := os.Open(file)
 		if err != nil {
diff --git a/internal/btf/core_test.go b/internal/btf/core_test.go
index e9a358b..593dded 100644
--- a/internal/btf/core_test.go
+++ b/internal/btf/core_test.go
@@ -12,7 +12,7 @@ import (
 	qt "github.com/frankban/quicktest"
 )
 
-func TestCoreAreTypesCompatible(t *testing.T) {
+func TestCOREAreTypesCompatible(t *testing.T) {
 	tests := []struct {
 		a, b       Type
 		compatible bool
@@ -83,7 +83,7 @@ func TestCoreAreTypesCompatible(t *testing.T) {
 	}
 }
 
-func TestCoreAreMembersCompatible(t *testing.T) {
+func TestCOREAreMembersCompatible(t *testing.T) {
 	tests := []struct {
 		a, b       Type
 		compatible bool
@@ -141,13 +141,13 @@ func TestCoreAreMembersCompatible(t *testing.T) {
 	}
 }
 
-func TestCoreAccessor(t *testing.T) {
+func TestCOREAccessor(t *testing.T) {
 	for _, valid := range []string{
 		"0",
 		"1:0",
 		"1:0:3:34:10:1",
 	} {
-		_, err := parseCoreAccessor(valid)
+		_, err := parseCOREAccessor(valid)
 		if err != nil {
 			t.Errorf("Parse %q: %s", valid, err)
 		}
@@ -161,14 +161,14 @@ func TestCoreAccessor(t *testing.T) {
 		":12",
 		"4294967296",
 	} {
-		_, err := parseCoreAccessor(invalid)
+		_, err := parseCOREAccessor(invalid)
 		if err == nil {
 			t.Errorf("Accepted invalid accessor %q", invalid)
 		}
 	}
 }
 
-func TestCoreFindEnumValue(t *testing.T) {
+func TestCOREFindEnumValue(t *testing.T) {
 	a := &Enum{Values: []EnumValue{{"foo", 23}, {"bar", 42}}}
 	b := &Enum{Values: []EnumValue{
 		{"foo___flavour", 0},
@@ -226,7 +226,7 @@ func TestCoreFindEnumValue(t *testing.T) {
 	}
 }
 
-func TestCoreFindField(t *testing.T) {
+func TestCOREFindField(t *testing.T) {
 	ptr := &Pointer{}
 	u16 := &Int{Size: 2}
 	u32 := &Int{Size: 4}
@@ -436,7 +436,7 @@ func TestCoreFindField(t *testing.T) {
 		},
 	}
 
-	checkCoreField := func(t *testing.T, got, want coreField) {
+	checkCOREField := func(t *testing.T, got, want coreField) {
 		t.Helper()
 		qt.Check(t, got.Type, qt.Equals, want.Type, qt.Commentf("type should match"))
 		qt.Check(t, got.offset, qt.Equals, want.offset, qt.Commentf("offset should match"))
@@ -446,13 +446,13 @@ func TestCoreFindField(t *testing.T) {
 		t.Run(test.name, func(t *testing.T) {
 			localField, targetField, err := coreFindField(test.local, test.acc, test.target)
 			qt.Assert(t, err, qt.IsNil)
-			checkCoreField(t, localField, test.localField)
-			checkCoreField(t, targetField, test.targetField)
+			checkCOREField(t, localField, test.localField)
+			checkCOREField(t, targetField, test.targetField)
 		})
 	}
 }
 
-func TestCoreFindFieldCyclical(t *testing.T) {
+func TestCOREFindFieldCyclical(t *testing.T) {
 	members := []Member{{Name: "foo", Type: &Pointer{}}}
 
 	cyclicStruct := &Struct{}
@@ -483,7 +483,7 @@ func TestCoreFindFieldCyclical(t *testing.T) {
 	}
 }
 
-func TestCoreRelocation(t *testing.T) {
+func TestCORERelocation(t *testing.T) {
 	testutils.Files(t, testutils.Glob(t, "testdata/*.elf"), func(t *testing.T, file string) {
 		rd, err := os.Open(file)
 		if err != nil {
@@ -509,7 +509,7 @@ func TestCoreRelocation(t *testing.T) {
 					t.Fatal("Retrieve program:", err)
 				}
 
-				relos, err := CORERelocate(prog.Spec(), spec, prog.CoreRelos)
+				relos, err := CORERelocate(prog.Spec(), spec, prog.CORERelos)
 				if want := errs[name]; want != nil {
 					if !errors.Is(err, want) {
 						t.Fatal("Expected", want, "got", err)
@@ -533,7 +533,7 @@ func TestCoreRelocation(t *testing.T) {
 	})
 }
 
-func TestCoreCopyWithoutQualifiers(t *testing.T) {
+func TestCORECopyWithoutQualifiers(t *testing.T) {
 	qualifiers := []struct {
 		name string
 		fn   func(Type) Type