Skip to content

Commit 89844e9

Browse files
committed
btf: reduce memory usage by skipping intermediate slices
We still construct full slices of various raw BTF types, only to discard them afterwards. Instead, decode only a single raw type and accumulate the inflated equivalents. Signed-off-by: Lorenz Bauer <[email protected]>
1 parent b2fa876 commit 89844e9

File tree

2 files changed

+106
-145
lines changed

2 files changed

+106
-145
lines changed

btf/btf_types.go

+35-63
Original file line numberDiff line numberDiff line change
@@ -397,21 +397,15 @@ type btfMember struct {
397397

398398
var btfMemberLen = int(unsafe.Sizeof(btfMember{}))
399399

400-
func unmarshalBtfMembers(members []btfMember, b []byte, bo binary.ByteOrder) (int, error) {
401-
off := 0
402-
for i := range members {
403-
if off+btfMemberLen > len(b) {
404-
return 0, fmt.Errorf("not enough bytes to unmarshal btfMember %d", i)
405-
}
406-
407-
members[i].NameOff = bo.Uint32(b[off+0:])
408-
members[i].Type = TypeID(bo.Uint32(b[off+4:]))
409-
members[i].Offset = bo.Uint32(b[off+8:])
410-
411-
off += btfMemberLen
400+
func unmarshalBtfMember(bm *btfMember, b []byte, bo binary.ByteOrder) (int, error) {
401+
if btfMemberLen > len(b) {
402+
return 0, fmt.Errorf("not enough bytes to unmarshal btfMember")
412403
}
413404

414-
return off, nil
405+
bm.NameOff = bo.Uint32(b[0:])
406+
bm.Type = TypeID(bo.Uint32(b[4:]))
407+
bm.Offset = bo.Uint32(b[8:])
408+
return btfMemberLen, nil
415409
}
416410

417411
type btfVarSecinfo struct {
@@ -422,21 +416,15 @@ type btfVarSecinfo struct {
422416

423417
var btfVarSecinfoLen = int(unsafe.Sizeof(btfVarSecinfo{}))
424418

425-
func unmarshalBtfVarSecInfos(secinfos []btfVarSecinfo, b []byte, bo binary.ByteOrder) (int, error) {
426-
off := 0
427-
for i := range secinfos {
428-
if off+btfVarSecinfoLen > len(b) {
429-
return 0, fmt.Errorf("not enough bytes to unmarshal btfVarSecinfo %d", i)
430-
}
431-
432-
secinfos[i].Type = TypeID(bo.Uint32(b[off+0:]))
433-
secinfos[i].Offset = bo.Uint32(b[off+4:])
434-
secinfos[i].Size = bo.Uint32(b[off+8:])
435-
436-
off += btfVarSecinfoLen
419+
func unmarshalBtfVarSecInfo(bvsi *btfVarSecinfo, b []byte, bo binary.ByteOrder) (int, error) {
420+
if len(b) < btfVarSecinfoLen {
421+
return 0, fmt.Errorf("not enough bytes to unmarshal btfVarSecinfo")
437422
}
438423

439-
return off, nil
424+
bvsi.Type = TypeID(bo.Uint32(b[0:]))
425+
bvsi.Offset = bo.Uint32(b[4:])
426+
bvsi.Size = bo.Uint32(b[8:])
427+
return btfVarSecinfoLen, nil
440428
}
441429

442430
type btfVariable struct {
@@ -461,20 +449,14 @@ type btfEnum struct {
461449

462450
var btfEnumLen = int(unsafe.Sizeof(btfEnum{}))
463451

464-
func unmarshalBtfEnums(enums []btfEnum, b []byte, bo binary.ByteOrder) (int, error) {
465-
off := 0
466-
for i := range enums {
467-
if off+btfEnumLen > len(b) {
468-
return 0, fmt.Errorf("not enough bytes to unmarshal btfEnum %d", i)
469-
}
470-
471-
enums[i].NameOff = bo.Uint32(b[off+0:])
472-
enums[i].Val = bo.Uint32(b[off+4:])
473-
474-
off += btfEnumLen
452+
func unmarshalBtfEnum(be *btfEnum, b []byte, bo binary.ByteOrder) (int, error) {
453+
if btfEnumLen > len(b) {
454+
return 0, fmt.Errorf("not enough bytes to unmarshal btfEnum")
475455
}
476456

477-
return off, nil
457+
be.NameOff = bo.Uint32(b[0:])
458+
be.Val = bo.Uint32(b[4:])
459+
return btfEnumLen, nil
478460
}
479461

480462
type btfEnum64 struct {
@@ -485,21 +467,16 @@ type btfEnum64 struct {
485467

486468
var btfEnum64Len = int(unsafe.Sizeof(btfEnum64{}))
487469

488-
func unmarshalBtfEnums64(enums []btfEnum64, b []byte, bo binary.ByteOrder) (int, error) {
489-
off := 0
490-
for i := range enums {
491-
if off+btfEnum64Len > len(b) {
492-
return 0, fmt.Errorf("not enough bytes to unmarshal btfEnum64 %d", i)
493-
}
494-
495-
enums[i].NameOff = bo.Uint32(b[off+0:])
496-
enums[i].ValLo32 = bo.Uint32(b[off+4:])
497-
enums[i].ValHi32 = bo.Uint32(b[off+8:])
498-
499-
off += btfEnum64Len
470+
func unmarshalBtfEnum64(enum *btfEnum64, b []byte, bo binary.ByteOrder) (int, error) {
471+
if len(b) < btfEnum64Len {
472+
return 0, fmt.Errorf("not enough bytes to unmarshal btfEnum64")
500473
}
501474

502-
return off, nil
475+
enum.NameOff = bo.Uint32(b[0:])
476+
enum.ValLo32 = bo.Uint32(b[4:])
477+
enum.ValHi32 = bo.Uint32(b[8:])
478+
479+
return btfEnum64Len, nil
503480
}
504481

505482
type btfParam struct {
@@ -509,20 +486,15 @@ type btfParam struct {
509486

510487
var btfParamLen = int(unsafe.Sizeof(btfParam{}))
511488

512-
func unmarshalBtfParams(params []btfParam, b []byte, bo binary.ByteOrder) (int, error) {
513-
off := 0
514-
for i := range params {
515-
if off+btfParamLen > len(b) {
516-
return 0, fmt.Errorf("not enough bytes to unmarshal btfParam %d", i)
517-
}
518-
519-
params[i].NameOff = bo.Uint32(b[off+0:])
520-
params[i].Type = TypeID(bo.Uint32(b[off+4:]))
521-
522-
off += btfParamLen
489+
func unmarshalBtfParam(param *btfParam, b []byte, bo binary.ByteOrder) (int, error) {
490+
if len(b) < btfParamLen {
491+
return 0, fmt.Errorf("not enough bytes to unmarshal btfParam")
523492
}
524493

525-
return off, nil
494+
param.NameOff = bo.Uint32(b[0:])
495+
param.Type = TypeID(bo.Uint32(b[4:]))
496+
497+
return btfParamLen, nil
526498
}
527499

528500
type btfDeclTag struct {

0 commit comments

Comments
 (0)