Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for function pointers #499

Merged
merged 3 commits into from
Dec 3, 2021

Conversation

pippolo84
Copy link
Member

@pippolo84 pippolo84 commented Nov 24, 2021

This PR adds support for function pointer relocations, following the same logic in libbpf: torvalds/linux@53eddb5

For example, this kind of relocation is needed when using helpers such as:
long bpf_for_each_map_elem(struct bpf_map *map, void *callback_fn, void *callback_ctx, u64 flags)
which takes a callback as a parameter.

The kernel selftests for_each_array_{array,map}_elem have been enabled as they should be supported now.

Fixes #467

Copy link
Collaborator

@lmb lmb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR! I've left a couple of comments, it looks good overall :)

Can you add some tests outside of the libbpf integration please? It's not trivial to debug those if they fail, and we're pretty lax when getting errors from these tests. I think you should be able to adjust loader.c to include a load of a function pointer.

elf_reader.go Outdated Show resolved Hide resolved
elf_reader.go Outdated Show resolved Hide resolved
elf_reader.go Outdated Show resolved Hide resolved
elf_reader.go Outdated Show resolved Hide resolved
linker.go Show resolved Hide resolved
linker.go Outdated Show resolved Hide resolved
@pippolo84
Copy link
Member Author

Thanks for the PR! I've left a couple of comments, it looks good overall :)

Can you add some tests outside of the libbpf integration please? It's not trivial to debug those if they fail, and we're pretty lax when getting errors from these tests. I think you should be able to adjust loader.c to include a load of a function pointer.

Hi @lmb , thank you for your comments. I'll polish the code and add some tests as you suggested.

@pippolo84 pippolo84 force-pushed the enhancement/support-function-pointers branch from 0af08c7 to 233574d Compare November 29, 2021 11:17
@pippolo84
Copy link
Member Author

pippolo84 commented Nov 29, 2021

I added a test in elf_reader_test.go for subprogram relocation. AFAIK this kind of relocation is supported from 5.13 onwards (running the test on with my distro kernel, v5.10, leads to a fail, instead it passes on a v5.15. And the same goes using libbpf).

To avoid complicating things too much in loader.c, I wrote a separate BPF program and Go test, adding testutils.SkipOnOldKernel to skip it for older kernel.

@pippolo84
Copy link
Member Author

I realized that I misunderstood the reason why the test needs a kernel >= 5.13.
I used the bpf helper for_each_map_elem, that's the reason for the requirement. Is this acceptable or should I modify the test to run on earlier kernel version?
I thought about using that helper because it seemed the most common case to exercise the subprogram relocation with ld_imm64 instruction.

Regarding the CI failure I find it surprising: maybe just a matter of flakyness? Unfortunately I am not able to see the output from the failing test on semaphore.

@pippolo84 pippolo84 requested a review from lmb November 30, 2021 23:13
Copy link
Collaborator

@lmb lmb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think requiring 5.13 for the test is OK as long as it's documented why. What use is there for subprog loads before for_each_map_elem appeared?

elf_reader.go Show resolved Hide resolved
offset := int64(int32(ins.Constant)+1) * asm.InstructionSize
if offset < 0 {
return fmt.Errorf("call: %s: invalid offset %d", name, offset)
case elf.STT_SECTION:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So a load of a static function doesn't require the same offset fixup as for Call?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

linker.go Show resolved Hide resolved
testdata/common.h Outdated Show resolved Hide resolved
elf_reader_test.go Outdated Show resolved Hide resolved
@pippolo84
Copy link
Member Author

I think requiring 5.13 for the test is OK as long as it's documented why. What use is there for subprog loads before for_each_map_elem appeared?

TBH I am not aware of any other case. Digging a little bit through the relevant kernel patches it seems that this kind of relocation has been introduced to support that helper in the first place: https://www.spinics.net/lists/bpf/msg35623.html

@pippolo84 pippolo84 requested a review from lmb December 2, 2021 17:16
Signed-off-by: Fabio Falzoi <fabio.falzoi84@gmail.com>
Signed-off-by: Fabio Falzoi <fabio.falzoi84@gmail.com>
Signed-off-by: Fabio Falzoi <fabio.falzoi84@gmail.com>
@lmb lmb force-pushed the enhancement/support-function-pointers branch from 84e9f21 to 8a464bd Compare December 3, 2021 10:56
@lmb lmb merged commit f10c3b2 into cilium:master Dec 3, 2021
@lmb
Copy link
Collaborator

lmb commented Dec 3, 2021

Thanks!

@pippolo84
Copy link
Member Author

Thanks!

Thank you for your review and comments!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

program: support function pointers
2 participants