associateStructOpsRelocs handles `.struct_ops.link` and associates the target function with the correct struct member in the map.
(progs map[string]*ProgramSpec)
| 1518 | // associateStructOpsRelocs handles `.struct_ops.link` |
| 1519 | // and associates the target function with the correct struct member in the map. |
| 1520 | func (ec *elfCode) associateStructOpsRelocs(progs map[string]*ProgramSpec) error { |
| 1521 | for _, sec := range ec.sections { |
| 1522 | if sec.kind != structOpsSection { |
| 1523 | continue |
| 1524 | } |
| 1525 | |
| 1526 | userData, err := sec.Data() |
| 1527 | if err != nil { |
| 1528 | return fmt.Errorf("failed to read section data: %w", err) |
| 1529 | } |
| 1530 | |
| 1531 | if ec.btf == nil { |
| 1532 | return fmt.Errorf("struct_ops section %s: missing BTF", sec.Name) |
| 1533 | } |
| 1534 | |
| 1535 | // Resolve the BTF datasec describing variables in this section. |
| 1536 | var ds *btf.Datasec |
| 1537 | if err := ec.btf.TypeByName(sec.Name, &ds); err != nil { |
| 1538 | return fmt.Errorf("datasec %s: %w", sec.Name, err) |
| 1539 | } |
| 1540 | |
| 1541 | // Set flags for .struct_ops.link (BPF_F_LINK). |
| 1542 | flags := uint32(0) |
| 1543 | if sec.Name == structOpsLinkSec { |
| 1544 | flags = sys.BPF_F_LINK |
| 1545 | } |
| 1546 | |
| 1547 | for _, vsi := range ds.Vars { |
| 1548 | userSt, baseOff, err := ec.createStructOpsMap(vsi, userData, flags) |
| 1549 | if err != nil { |
| 1550 | return err |
| 1551 | } |
| 1552 | |
| 1553 | if err := structOpsSetAttachTo(sec, baseOff, userSt, progs); err != nil { |
| 1554 | return err |
| 1555 | } |
| 1556 | } |
| 1557 | } |
| 1558 | |
| 1559 | return nil |
| 1560 | } |
| 1561 | |
| 1562 | // createStructOpsMap() creates and registers a MapSpec for a struct_ops |
| 1563 | func (ec *elfCode) createStructOpsMap(vsi btf.VarSecinfo, userData []byte, flags uint32) (*btf.Struct, uint32, error) { |
no test coverage detected