diff --git a/src/io/elf_map_parser.cpp b/src/io/elf_map_parser.cpp index ad3320d2f..2f570166f 100644 --- a/src/io/elf_map_parser.cpp +++ b/src/io/elf_map_parser.cpp @@ -295,27 +295,38 @@ ElfGlobalData parse_map_sections(const parse_params_t& parse_params, const ELFIO ElfGlobalData extract_global_data(const parse_params_t& params, const ELFIO::elfio& reader, const ELFIO::const_symbol_section_accessor& symbols) { - if (reader.sections[".BTF"] && reader.sections[".maps"]) { - try { + ElfGlobalData global = [&] { + if (reader.sections[".BTF"] && reader.sections[".maps"]) { + try { + return parse_btf_section(params, reader); + } catch (const UnmarshalError& e) { + // BTF-defined maps can't be decoded; fall back to section-based map descriptors. + std::cerr << "BTF map parsing failed, falling back to section-based maps: " << e.what() << std::endl; + return parse_map_sections(params, reader, symbols); + } + } + if (std::ranges::any_of(reader.sections, [](const auto& s) { return is_map_section(s->get_name()); })) { + return parse_map_sections(params, reader, symbols); + } + if (reader.sections[".BTF"]) { return parse_btf_section(params, reader); - } catch (const UnmarshalError& e) { - // BTF-defined maps can't be decoded; fall back to section-based map descriptors. - std::cerr << "BTF map parsing failed, falling back to section-based maps: " << e.what() << std::endl; } - return parse_map_sections(params, reader, symbols); - } - - const bool has_legacy_maps = - std::ranges::any_of(reader.sections, [](const auto& s) { return is_map_section(s->get_name()); }); - if (has_legacy_maps) { - return parse_map_sections(params, reader, symbols); - } + return create_global_variable_maps(reader); + }(); - if (reader.sections[".BTF"]) { - return parse_btf_section(params, reader); + /// Mark descriptors that serve only as inner map templates. + /// At runtime the actual inner map can be any map with matching structure, + /// not necessarily the template defined in the ELF. + for (const auto& desc : global.map_descriptors) { + if (desc.inner_map_fd != DEFAULT_MAP_FD) { + for (auto& inner_desc : global.map_descriptors) { + if (inner_desc.original_fd == desc.inner_map_fd) { + inner_desc.is_inner_map_template = true; + } + } + } } - - return create_global_variable_maps(reader); + return global; } void update_line_info(std::vector& raw_programs, const ELFIO::section* btf_section, diff --git a/src/spec/type_descriptors.hpp b/src/spec/type_descriptors.hpp index e298eaab9..52ea7745b 100644 --- a/src/spec/type_descriptors.hpp +++ b/src/spec/type_descriptors.hpp @@ -30,7 +30,8 @@ struct EbpfMapDescriptor { unsigned int value_size; unsigned int max_entries; int inner_map_fd; - std::string name; // Map name from ELF (empty if not available). + std::string name; // Map name from ELF (empty if not available). + bool is_inner_map_template{false}; // True if this descriptor is referenced as an inner map template. }; struct EbpfProgramType {