bpf2c: emit maps in order they appear in ELF file (#883)

* bugfix

* Update tests/api_test/api_test.cpp

Co-authored-by: Dave Thaler <dthaler@microsoft.com>

Co-authored-by: Dave Thaler <dthaler@microsoft.com>
This commit is contained in:
saxena-anurag 2022-04-05 15:16:02 -07:00 коммит произвёл GitHub
Родитель b9d46ae8e4
Коммит 68a740223c
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 51 добавлений и 19 удалений

Просмотреть файл

@ -562,6 +562,17 @@ TEST_CASE("bindmonitor_tailcall_native_test", "[native_tests]")
cleanup();
REQUIRE(outer_map_fd > 0);
// Cleanup tail calls.
// Test map-in-maps.
struct bpf_map* outer_idx_map = bpf_object__find_map_by_name(object, "dummy_outer_idx_map");
if (outer_idx_map == nullptr)
cleanup();
REQUIRE(outer_idx_map != nullptr);
int outer_idx_map_fd = bpf_map__fd(outer_idx_map);
if (outer_idx_map_fd <= 0)
cleanup();
REQUIRE(outer_idx_map_fd > 0);
// Clean up tail calls.
cleanup();
}

Просмотреть файл

@ -59,6 +59,14 @@ struct _ebpf_map_definition_in_file dummy_outer_map = {
// inner_id refers to the id of the inner map in the same ELF object.
.inner_id = INNER_MAP_ID};
SEC("maps")
struct _ebpf_map_definition_in_file dummy_outer_idx_map = {
.type = BPF_MAP_TYPE_HASH_OF_MAPS,
.key_size = sizeof(uint32_t),
.value_size = sizeof(uint32_t),
.max_entries = 10,
.inner_map_idx = 6};
SEC("maps")
struct _ebpf_map_definition_in_file dummy_inner_map = {
.type = BPF_MAP_TYPE_HASH,

Просмотреть файл

@ -216,6 +216,14 @@ bpf_code_generator::parse()
ELFIO::const_symbol_section_accessor symbols{reader, reader.sections[".symtab"]};
if (map_section) {
size_t data_size = map_section->get_size();
if (data_size % sizeof(ebpf_map_definition_in_file_t) != 0) {
throw std::runtime_error(
std::string("bad maps section size, must be a multiple of ") +
std::to_string(sizeof(ebpf_map_definition_in_file_t)));
}
for (ELFIO::Elf_Xword i = 0; i < symbols.get_symbols_num(); i++) {
std::string symbol_name;
ELFIO::Elf64_Addr symbol_value{};
@ -241,15 +249,11 @@ bpf_code_generator::parse()
}
map_definitions[symbol_name].definition =
*reinterpret_cast<const ebpf_map_definition_in_file_t*>(map_section->get_data() + symbol_value);
map_definitions[symbol_name].index = symbol_value / sizeof(ebpf_map_definition_in_file_t);
}
}
}
// Assign index to each map
size_t map_index = 0;
for (auto& map : map_definitions) {
map.second.index = map_index++;
}
}
void
@ -646,18 +650,27 @@ bpf_code_generator::emit_c_code(std::ostream& output_stream)
// Emit import tables
if (map_definitions.size() > 0) {
output_stream << "static map_entry_t _maps[] = {" << std::endl;
for (const auto& map : map_definitions) {
output_stream << "{ NULL, { ";
output_stream << map.second.definition.size << ", ";
output_stream << map.second.definition.type << ", ";
output_stream << map.second.definition.key_size << ", ";
output_stream << map.second.definition.value_size << ", ";
output_stream << map.second.definition.max_entries << ", ";
output_stream << map.second.definition.inner_map_idx << ", ";
output_stream << map.second.definition.pinning << ", ";
output_stream << map.second.definition.id << ", ";
output_stream << map.second.definition.inner_id << ", ";
output_stream << " }, \"" << map.first.c_str() << "\" }," << std::endl;
size_t map_size = map_definitions.size();
size_t current_index = 0;
while (current_index < map_size) {
for (const auto& [name, entry] : map_definitions) {
if (entry.index == current_index) {
output_stream << "{ NULL, { ";
output_stream << entry.definition.size << ", ";
output_stream << entry.definition.type << ", ";
output_stream << entry.definition.key_size << ", ";
output_stream << entry.definition.value_size << ", ";
output_stream << entry.definition.max_entries << ", ";
output_stream << entry.definition.inner_map_idx << ", ";
output_stream << entry.definition.pinning << ", ";
output_stream << entry.definition.id << ", ";
output_stream << entry.definition.inner_id << ", ";
output_stream << " }, \"" << name.c_str() << "\" }," << std::endl;
current_index++;
break;
}
}
}
output_stream << "};" << std::endl;
output_stream << std::endl;