-
Notifications
You must be signed in to change notification settings - Fork 54
lib: add bf_vector and use it in cgen #487
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -54,7 +54,6 @@ | |
|
|
||
| #define _BF_LOG_BUF_SIZE \ | ||
| (UINT32_MAX >> 8) /* verifier maximum in kernels <= 5.1 */ | ||
| #define _BF_PROGRAM_DEFAULT_IMG_SIZE (1 << 6) | ||
| #define _BF_LOG_MAP_N_ENTRIES 1000 | ||
| #define _BF_LOG_MAP_SIZE \ | ||
| _bf_round_next_power_of_2(sizeof(struct bf_log) * _BF_LOG_MAP_N_ENTRIES) | ||
|
|
@@ -107,6 +106,7 @@ int bf_program_new(struct bf_program **program, const struct bf_chain *chain, | |
| _program->flavor = bf_hook_to_flavor(chain->hook); | ||
| _program->runtime.ops = bf_flavor_ops_get(_program->flavor); | ||
| _program->runtime.chain = chain; | ||
| _program->img = bf_vector_default(sizeof(struct bpf_insn)); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Claude: suggestion: The old Consider adding an initial reserve in _program->img = bf_vector_default(sizeof(struct bpf_insn));
bf_vector_reserve(&_program->img, 64);Alternatively, the caller-side reserve preserves the generic
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 with Claude, programs are at least 200 instructions, so we can reserve |
||
| _program->fixups = bf_list_default(bf_fixup_free, NULL); | ||
| _program->handle = handle; | ||
|
|
||
|
|
@@ -125,7 +125,7 @@ void bf_program_free(struct bf_program **program) | |
| return; | ||
|
|
||
| bf_list_clean(&(*program)->fixups); | ||
| free((*program)->img); | ||
| bf_vector_clean(&(*program)->img); | ||
|
|
||
| bf_printer_free(&(*program)->printer); | ||
|
|
||
|
|
@@ -152,9 +152,9 @@ void bf_program_dump(const struct bf_program *program, prefix_t *prefix) | |
| bf_printer_dump(program->printer, prefix); | ||
| bf_dump_prefix_pop(prefix); | ||
|
|
||
| DUMP(prefix, "img: %p", program->img); | ||
| DUMP(prefix, "img_size: %lu", program->img_size); | ||
| DUMP(prefix, "img_cap: %lu", program->img_cap); | ||
| DUMP(prefix, "img: %p", program->img.data); | ||
| DUMP(prefix, "img.size: %lu", program->img.size); | ||
| DUMP(prefix, "img.cap: %lu", program->img.cap); | ||
|
|
||
| DUMP(prefix, "fixups: bf_list<struct bf_fixup>[%lu]", | ||
| bf_list_size(&program->fixups)); | ||
|
|
@@ -177,27 +177,6 @@ void bf_program_dump(const struct bf_program *program, prefix_t *prefix) | |
| bf_dump_prefix_pop(prefix); | ||
| } | ||
|
|
||
| int bf_program_grow_img(struct bf_program *program) | ||
| { | ||
| size_t new_cap = _BF_PROGRAM_DEFAULT_IMG_SIZE; | ||
| int r; | ||
|
|
||
| assert(program); | ||
|
|
||
| if (program->img) | ||
| new_cap = _bf_round_next_power_of_2(program->img_cap << 1); | ||
|
|
||
| r = bf_realloc((void **)&program->img, new_cap * sizeof(struct bpf_insn)); | ||
| if (r < 0) { | ||
| return bf_err_r(r, "failed to grow program img from %lu to %lu insn", | ||
| program->img_cap, new_cap); | ||
| } | ||
|
|
||
| program->img_cap = new_cap; | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| static void _bf_program_fixup_insn(struct bpf_insn *insn, | ||
| enum bf_fixup_insn type, int32_t value) | ||
| { | ||
|
|
@@ -230,16 +209,23 @@ static int _bf_program_fixup(struct bf_program *program, | |
| int32_t value; | ||
| size_t offset; | ||
| struct bf_fixup *fixup = bf_list_node_get_data(fixup_node); | ||
| struct bpf_insn *insn = &program->img[fixup->insn]; | ||
| struct bpf_insn *insn; | ||
| struct bf_map *map; | ||
|
|
||
| if (type != fixup->type) | ||
| continue; | ||
|
|
||
| insn = bf_vector_get(&program->img, fixup->insn); | ||
| if (!insn) { | ||
pzmarzly marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return bf_err_r(-EINVAL, | ||
| "fixup references invalid instruction index %lu", | ||
| fixup->insn); | ||
| } | ||
|
|
||
| switch (type) { | ||
| case BF_FIXUP_TYPE_JMP_NEXT_RULE: | ||
| insn_type = BF_FIXUP_INSN_OFF; | ||
| value = (int)(program->img_size - fixup->insn - 1U); | ||
| value = (int)(program->img.size - fixup->insn - 1U); | ||
| break; | ||
| case BF_FIXUP_TYPE_COUNTERS_MAP_FD: | ||
| insn_type = BF_FIXUP_INSN_IMM; | ||
|
|
@@ -413,7 +399,7 @@ static int _bf_program_generate_elfstubs(struct bf_program *program) | |
|
|
||
| bf_list_foreach (&program->fixups, fixup_node) { | ||
| struct bf_fixup *fixup = bf_list_node_get_data(fixup_node); | ||
| size_t off = program->img_size; | ||
| size_t off = program->img.size; | ||
|
|
||
| if (fixup->type != BF_FIXUP_ELFSTUB_CALL) | ||
| continue; | ||
|
|
@@ -430,7 +416,7 @@ static int _bf_program_generate_elfstubs(struct bf_program *program) | |
| fixup->attr.elfstub_id); | ||
| } | ||
|
|
||
| start_at = program->img_size; | ||
| start_at = program->img.size; | ||
|
|
||
| for (size_t i = 0; i < elfstub->ninsns; ++i) { | ||
| r = bf_program_emit(program, elfstub->insns[i]); | ||
|
|
@@ -451,8 +437,18 @@ static int _bf_program_generate_elfstubs(struct bf_program *program) | |
| ld_insn[0].src_reg = BPF_PSEUDO_MAP_VALUE; | ||
| ld_insn[1].imm = (int)bf_printer_msg_offset(msg); | ||
|
|
||
| program->img[insn_idx] = ld_insn[0]; | ||
| program->img[insn_idx + 1] = ld_insn[1]; | ||
| r = bf_vector_set(&program->img, insn_idx, &ld_insn[0]); | ||
| if (r) { | ||
| return bf_err_r( | ||
| r, "failed to set ELF stub instruction at index %lu", | ||
| insn_idx); | ||
| } | ||
| r = bf_vector_set(&program->img, insn_idx + 1, &ld_insn[1]); | ||
| if (r) { | ||
| return bf_err_r( | ||
| r, "failed to set ELF stub instruction at index %lu", | ||
| insn_idx + 1); | ||
| } | ||
|
|
||
| r = bf_fixup_new(&fixup, BF_FIXUP_TYPE_PRINTER_MAP_FD, insn_idx, | ||
| NULL); | ||
|
|
@@ -474,19 +470,9 @@ static int _bf_program_generate_elfstubs(struct bf_program *program) | |
|
|
||
| int bf_program_emit(struct bf_program *program, struct bpf_insn insn) | ||
| { | ||
| int r; | ||
|
|
||
| assert(program); | ||
|
|
||
| if (program->img_size == program->img_cap) { | ||
| r = bf_program_grow_img(program); | ||
| if (r) | ||
| return r; | ||
| } | ||
|
|
||
| program->img[program->img_size++] = insn; | ||
|
|
||
| return 0; | ||
| return bf_vector_add(&program->img, &insn); | ||
| } | ||
|
Comment on lines
471
to
476
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| int bf_program_emit_kfunc_call(struct bf_program *program, const char *name) | ||
|
|
@@ -517,13 +503,11 @@ int bf_program_emit_fixup(struct bf_program *program, enum bf_fixup_type type, | |
|
|
||
| assert(program); | ||
|
|
||
| if (program->img_size == program->img_cap) { | ||
| r = bf_program_grow_img(program); | ||
| if (r) | ||
| return r; | ||
| } | ||
| r = bf_vector_reserve(&program->img, program->img.size + 1); | ||
| if (r) | ||
| return r; | ||
|
|
||
| r = bf_fixup_new(&fixup, type, program->img_size, attr); | ||
| r = bf_fixup_new(&fixup, type, program->img.size, attr); | ||
pzmarzly marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if (r) | ||
| return r; | ||
|
|
||
|
|
@@ -535,8 +519,8 @@ int bf_program_emit_fixup(struct bf_program *program, enum bf_fixup_type type, | |
|
|
||
| /* This call could fail and return an error, in which case it is not | ||
| * properly handled. However, this shouldn't be an issue as we previously | ||
| * test whether enough room is available in cgen.img, which is currently | ||
| * the only reason for EMIT() to fail. */ | ||
| * reserved enough room in program->img, which is currently the only | ||
| * reason for EMIT() to fail. */ | ||
| EMIT(program, insn); | ||
|
Comment on lines
506
to
524
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The original code is weird in order to ensure the state of We don't need to maintain a valid |
||
|
|
||
| return 0; | ||
|
|
@@ -550,13 +534,11 @@ int bf_program_emit_fixup_elfstub(struct bf_program *program, | |
|
|
||
| assert(program); | ||
|
|
||
| if (program->img_size == program->img_cap) { | ||
| r = bf_program_grow_img(program); | ||
| if (r) | ||
| return r; | ||
| } | ||
| r = bf_vector_reserve(&program->img, program->img.size + 1); | ||
| if (r) | ||
| return r; | ||
|
|
||
| r = bf_fixup_new(&fixup, BF_FIXUP_ELFSTUB_CALL, program->img_size, NULL); | ||
| r = bf_fixup_new(&fixup, BF_FIXUP_ELFSTUB_CALL, program->img.size, NULL); | ||
| if (r) | ||
| return r; | ||
|
|
||
|
|
@@ -808,13 +790,13 @@ int bf_program_load(struct bf_program *prog) | |
|
|
||
| r = bf_bpf_prog_load(prog->handle->prog_name, | ||
| bf_hook_to_bpf_prog_type(prog->runtime.chain->hook), | ||
| prog->img, prog->img_size, | ||
| prog->img.data, prog->img.size, | ||
| bf_hook_to_bpf_attach_type(prog->runtime.chain->hook), | ||
| log_buf, log_buf ? _BF_LOG_BUF_SIZE : 0, | ||
| bf_ctx_token(), &prog->handle->prog_fd); | ||
| if (r) { | ||
| return bf_err_r(r, "failed to load bf_program (%lu bytes):\n%s\nerrno:", | ||
| prog->img_size, log_buf ? log_buf : "<NO LOG BUFFER>"); | ||
| return bf_err_r(r, "failed to load bf_program (%lu insns):\n%s\nerrno:", | ||
| prog->img.size, log_buf ? log_buf : "<NO LOG BUFFER>"); | ||
pzmarzly marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| return r; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This variable should be defined at the beginning of the scope.