@@ -1419,7 +1419,6 @@ func (ec *elfCode) loadKsymsSection() error {
14191419// ".struct_ops" and ".struct_ops.link" found in the object BTF.
14201420func (ec * elfCode ) loadStructOpsMaps () error {
14211421 for secIdx , sec := range ec .sections {
1422- fmt .Println (sec .Name , sec .Type , sec .kind == structOpsSection )
14231422 if sec .kind != structOpsSection {
14241423 continue
14251424 }
@@ -1502,7 +1501,7 @@ func (ec *elfCode) associateStructOpsRelocs(
15021501 symbols []elf.Symbol ,
15031502) error {
15041503 for _ , sec := range relSecs {
1505- if ! strings . HasPrefix (sec .Name , ".rel" ) {
1504+ if ! (sec .Type == elf . SHT_REL ) {
15061505 continue
15071506 }
15081507
@@ -1544,35 +1543,45 @@ func (ec *elfCode) associateStructOpsRelocs(
15441543 return fmt .Errorf ("no struct_ops map found for secIdx %d and relOffset %d" , targetIdx , relOff )
15451544 }
15461545
1546+ // Member bit offset inside the user struct
15471547 moff := btf .Bits ((relOff - meta .userOff ) * 8 )
15481548
15491549 userSt , ok := btf.As [* btf.Struct ](ms .Value )
15501550 if ! ok {
15511551 return fmt .Errorf ("provided value is not a btf.Struct" )
15521552 }
15531553
1554- for _ , m := range userSt .Members {
1555- if m .Offset != moff {
1556- continue
1557- }
1558-
1559- mType := btf .UnderlyingType (m .Type )
1560- if mPtr , isPtr := btf.As [* btf.Pointer ](mType ); isPtr {
1561- if _ , isFuncProto := btf.As [* btf.FuncProto ](mPtr .Target ); isFuncProto {
1562- p , ok := progs [sym .Name ]
1563- if ! (ok && p .Type == StructOps ) {
1564- return fmt .Errorf ("program %q not found or not StructOps" , sym .Name )
1565- }
1566- p .AttachTo = userSt .Name + ":" + m .Name
1567- }
1554+ // Find the member at moff and ensure it's a pointer to a FuncProto.
1555+ if memberName , found := funcPtrMemberAtOffset (userSt , moff ); found {
1556+ p , ok := progs [sym .Name ]
1557+ if ! (ok && p .Type == StructOps ) {
1558+ return fmt .Errorf ("program %q not found or not StructOps" , sym .Name )
15681559 }
1560+ p .AttachTo = userSt .Name + ":" + memberName
15691561 }
15701562 }
15711563 }
15721564
15731565 return nil
15741566}
15751567
1568+ // funcPtrMemberAtOffset returns the member name at bit offset `moff`
1569+ // if the member is a pointer to a FuncProto. Otherwise returns an empty string.
1570+ func funcPtrMemberAtOffset (userSt * btf.Struct , moff btf.Bits ) (string , bool ) {
1571+ for _ , m := range userSt .Members {
1572+ if m .Offset != moff {
1573+ continue
1574+ }
1575+ mt := btf .UnderlyingType (m .Type )
1576+ if ptr , ok := btf.As [* btf.Pointer ](mt ); ok {
1577+ if _ , ok := btf.As [* btf.FuncProto ](ptr .Target ); ok {
1578+ return m .Name , true
1579+ }
1580+ }
1581+ }
1582+ return "" , false
1583+ }
1584+
15761585type libbpfElfSectionDef struct {
15771586 pattern string
15781587 programType sys.ProgType
0 commit comments