Repository: cilium/ebpf
Pull request #690 (2022-05-27 13:46:57)

btf: add btfInt
Replace intEncoding with a type. This allows adding setters.


Patch:
diff --git a/btf/btf_types.go b/btf/btf_types.go
index a62b3c9..4810180 100644
--- a/btf/btf_types.go
+++ b/btf/btf_types.go
@@ -130,13 +130,22 @@ func mask(len uint32) uint32 {
 	return (1 << len) - 1
 }
 
+func readBits(value, len, shift uint32) uint32 {
+	return (value >> shift) & mask(len)
+}
+
+func writeBits(value, len, shift, new uint32) uint32 {
+	value &^= mask(len) << shift
+	value |= (new & mask(len)) << shift
+	return value
+}
+
 func (bt *btfType) info(len, shift uint32) uint32 {
-	return (bt.Info >> shift) & mask(len)
+	return readBits(bt.Info, len, shift)
 }
 
 func (bt *btfType) setInfo(value, len, shift uint32) {
-	bt.Info &^= mask(len) << shift
-	bt.Info |= (value & mask(len)) << shift
+	bt.Info = writeBits(bt.Info, len, shift, value)
 }
 
 func (bt *btfType) Kind() btfKind {
@@ -198,6 +207,50 @@ func (rt *rawType) Marshal(w io.Writer, bo binary.ByteOrder) error {
 	return binary.Write(w, bo, rt.data)
 }
 
+// btfInt encodes additional data for integers.
+//
+//    ? ? ? ? e e e e o o o o o o o o ? ? ? ? ? ? ? ? b b b b b b b b
+//    ? = undefined
+//    e = encoding
+//    o = offset (bitfields?)
+//    b = bits (bitfields)
+type btfInt struct {
+	Raw uint32
+}
+
+const (
+	btfIntEncodingLen   = 4
+	btfIntEncodingShift = 24
+	btfIntOffsetLen     = 8
+	btfIntOffsetShift   = 16
+	btfIntBitsLen       = 8
+	btfIntBitsShift     = 0
+)
+
+func (bi btfInt) Encoding() IntEncoding {
+	return IntEncoding(readBits(bi.Raw, btfIntEncodingLen, btfIntEncodingShift))
+}
+
+func (bi *btfInt) SetEncoding(e IntEncoding) {
+	bi.Raw = writeBits(uint32(bi.Raw), btfIntEncodingLen, btfIntEncodingShift, uint32(e))
+}
+
+func (bi btfInt) Offset() Bits {
+	return Bits(readBits(bi.Raw, btfIntOffsetLen, btfIntOffsetShift))
+}
+
+func (bi *btfInt) SetOffset(offset uint32) {
+	bi.Raw = writeBits(bi.Raw, btfIntOffsetLen, btfIntOffsetShift, offset)
+}
+
+func (bi btfInt) Bits() Bits {
+	return Bits(readBits(bi.Raw, btfIntBitsLen, btfIntBitsShift))
+}
+
+func (bi *btfInt) SetBits(bits byte) {
+	bi.Raw = writeBits(bi.Raw, btfIntBitsLen, btfIntBitsShift, uint32(bits))
+}
+
 type btfArray struct {
 	Type      TypeID
 	IndexType TypeID
@@ -249,7 +302,7 @@ func readTypes(r io.Reader, bo binary.ByteOrder, typeLen uint32) ([]rawType, err
 		var data interface{}
 		switch header.Kind() {
 		case kindInt:
-			data = new(uint32)
+			data = new(btfInt)
 		case kindPointer:
 		case kindArray:
 			data = new(btfArray)
@@ -288,7 +341,3 @@ func readTypes(r io.Reader, bo binary.ByteOrder, typeLen uint32) ([]rawType, err
 		types = append(types, rawType{header, data})
 	}
 }
-
-func intEncoding(raw uint32) (IntEncoding, Bits, Bits) {
-	return IntEncoding((raw & 0x0f000000) >> 24), Bits(raw&0x00ff0000) >> 16, Bits(raw & 0x000000ff)
-}
diff --git a/btf/types.go b/btf/types.go
index dad6e90..5aabd53 100644
--- a/btf/types.go
+++ b/btf/types.go
@@ -896,11 +896,11 @@ func inflateRawTypes(rawTypes []rawType, rawStrings *stringTable) ([]Type, error
 		switch raw.Kind() {
 		case kindInt:
 			size := raw.Size()
-			encoding, offset, bits := intEncoding(*raw.data.(*uint32))
-			if offset > 0 || bits.Bytes() != size {
-				legacyBitfields[id] = [2]Bits{offset, bits}
+			bi := raw.data.(*btfInt)
+			if bi.Offset() > 0 || bi.Bits().Bytes() != size {
+				legacyBitfields[id] = [2]Bits{bi.Offset(), bi.Bits()}
 			}
-			typ = &Int{name, size, encoding}
+			typ = &Int{name, raw.Size(), bi.Encoding()}
 
 		case kindPointer:
 			ptr := &Pointer{nil}


Test patch:
diff --git a/btf/types_test.go b/btf/types_test.go
index 97e868d..2d4abba 100644
--- a/btf/types_test.go
+++ b/btf/types_test.go
@@ -360,8 +360,10 @@ func TestInflateLegacyBitfield(t *testing.T) {
 	var rawInt rawType
 	rawInt.SetKind(kindInt)
 	rawInt.SetSize(4)
-	offsetSize := uint32(offset<<16 | size)
-	rawInt.data = &offsetSize
+	var data btfInt
+	data.SetOffset(offset)
+	data.SetBits(size)
+	rawInt.data = &data
 
 	var beforeInt rawType
 	beforeInt.SetKind(kindStruct)