Use less verbose names in BTF relocation code and fix off-by-one error and typo in btf_relocate.c. Simplify loop over matching distilled types, moving from assigning a _next value in loop body to moving match check conditions into the guard.
Unified · Split
| @@ -160,7 +160,7 @@ static int btf_mark_embedded_composite_type_ids(struct btf_relocate *r, __u32 i) · 159 unmodified lines | |||
| 160 | */ | 160 | */ |
| 161 | static int btf_relocate_map_distilled_base(struct btf_relocate *r) | 161 | static int btf_relocate_map_distilled_base(struct btf_relocate *r) |
| 162 | { | 162 | { |
| 163 | struct btf_name_info *dist_base_info_sorted, *dist_base_info_sorted_end; | 163 | struct btf_name_info *info, *info_end; |
| 164 | struct btf_type *base_t, *dist_t; | 164 | struct btf_type *base_t, *dist_t; |
| 165 | __u8 *base_name_cnt = NULL; | 165 | __u8 *base_name_cnt = NULL; |
| 166 | int err = 0; | 166 | int err = 0; |
| @@ -169,26 +169,24 @@ static int btf_relocate_map_distilled_base(struct btf_relocate *r) · 2 unmodified lines | |||
| 169 | /* generate a sort index array of name/type ids sorted by name for | 169 | /* generate a sort index array of name/type ids sorted by name for |
| 170 | * distilled base BTF to speed name-based lookups. | 170 | * distilled base BTF to speed name-based lookups. |
| 171 | */ | 171 | */ |
| 172 | dist_base_info_sorted = calloc(r->nr_dist_base_types, sizeof(*dist_base_info_sorted)); | 172 | info = calloc(r->nr_dist_base_types, sizeof(*info)); |
| 173 | if (!dist_base_info_sorted) { | 173 | if (!info) { |
| 174 | err = -ENOMEM; | 174 | err = -ENOMEM; |
| 175 | goto done; | 175 | goto done; |
| 176 | } | 176 | } |
| 177 | dist_base_info_sorted_end = dist_base_info_sorted + r->nr_dist_base_types; | 177 | info_end = info + r->nr_dist_base_types; |
| 178 | for (id = 0; id < r->nr_dist_base_types; id++) { | 178 | for (id = 0; id < r->nr_dist_base_types; id++) { |
| 179 | dist_t = btf_type_by_id(r->dist_base_btf, id); | 179 | dist_t = btf_type_by_id(r->dist_base_btf, id); |
| 180 | dist_base_info_sorted[id].name = btf__name_by_offset(r->dist_base_btf, | 180 | info[id].name = btf__name_by_offset(r->dist_base_btf, dist_t->name_off); |
| 181 | dist_t->name_off); | 181 | info[id].id = id; |
| 182 | dist_base_info_sorted[id].id = id; | 182 | info[id].size = dist_t->size; |
| 183 | dist_base_info_sorted[id].size = dist_t->size; | 183 | info[id].needs_size = true; |
| 184 | dist_base_info_sorted[id].needs_size = true; | ||
| 185 | } | 184 | } |
| 186 | qsort(dist_base_info_sorted, r->nr_dist_base_types, sizeof(*dist_base_info_sorted), | 185 | qsort(info, r->nr_dist_base_types, sizeof(*info), cmp_btf_name_size); |
| 187 | cmp_btf_name_size); | ||
| 188 | 186 | ||
| 189 | /* Mark distilled base struct/union members of split BTF structs/unions | 187 | /* Mark distilled base struct/union members of split BTF structs/unions |
| 190 | * in id_map with BTF_IS_EMBEDDED; this signals that these types | 188 | * in id_map with BTF_IS_EMBEDDED; this signals that these types |
| 191 | * need to match both name and size, otherwise embeddding the base | 189 | * need to match both name and size, otherwise embedding the base |
| 192 | * struct/union in the split type is invalid. | 190 | * struct/union in the split type is invalid. |
| 193 | */ | 191 | */ |
| 194 | for (id = r->nr_dist_base_types; id < r->nr_split_types; id++) { | 192 | for (id = r->nr_dist_base_types; id < r->nr_split_types; id++) { |
| @@ -216,8 +214,7 @@ static int btf_relocate_map_distilled_base(struct btf_relocate *r) · 21 unmodified lines | |||
| 216 | 214 | ||
| 217 | /* Now search base BTF for matching distilled base BTF types. */ | 215 | /* Now search base BTF for matching distilled base BTF types. */ |
| 218 | for (id = 1; id < r->nr_base_types; id++) { | 216 | for (id = 1; id < r->nr_base_types; id++) { |
| 219 | struct btf_name_info *dist_name_info, *dist_name_info_next = NULL; | 217 | struct btf_name_info *dist_info, base_info = {}; |
| 220 | struct btf_name_info base_name_info = {}; | ||
| 221 | int dist_kind, base_kind; | 218 | int dist_kind, base_kind; |
| 222 | 219 | ||
| 223 | base_t = btf_type_by_id(r->base_btf, id); | 220 | base_t = btf_type_by_id(r->base_btf, id); |
| @@ -225,16 +222,16 @@ static int btf_relocate_map_distilled_base(struct btf_relocate *r) · 1 unmodified line | |||
| 225 | if (!base_t->name_off) | 222 | if (!base_t->name_off) |
| 226 | continue; | 223 | continue; |
| 227 | base_kind = btf_kind(base_t); | 224 | base_kind = btf_kind(base_t); |
| 228 | base_name_info.id = id; | 225 | base_info.id = id; |
| 229 | base_name_info.name = btf__name_by_offset(r->base_btf, base_t->name_off); | 226 | base_info.name = btf__name_by_offset(r->base_btf, base_t->name_off); |
| 230 | switch (base_kind) { | 227 | switch (base_kind) { |
| 231 | case BTF_KIND_INT: | 228 | case BTF_KIND_INT: |
| 232 | case BTF_KIND_FLOAT: | 229 | case BTF_KIND_FLOAT: |
| 233 | case BTF_KIND_ENUM: | 230 | case BTF_KIND_ENUM: |
| 234 | case BTF_KIND_ENUM64: | 231 | case BTF_KIND_ENUM64: |
| 235 | /* These types should match both name and size */ | 232 | /* These types should match both name and size */ |
| 236 | base_name_info.needs_size = true; | 233 | base_info.needs_size = true; |
| 237 | base_name_info.size = base_t->size; | 234 | base_info.size = base_t->size; |
| 238 | break; | 235 | break; |
| 239 | case BTF_KIND_FWD: | 236 | case BTF_KIND_FWD: |
| 240 | /* No size considerations for fwds. */ | 237 | /* No size considerations for fwds. */ |
| @@ -248,31 +245,24 @@ static int btf_relocate_map_distilled_base(struct btf_relocate *r) · 7 unmodified lines | |||
| 248 | * unless corresponding _base_ types to match them are | 245 | * unless corresponding _base_ types to match them are |
| 249 | * missing. | 246 | * missing. |
| 250 | */ | 247 | */ |
| 251 | base_name_info.needs_size = base_name_cnt[base_t->name_off] > 1; | 248 | base_info.needs_size = base_name_cnt[base_t->name_off] > 1; |
| 252 | base_name_info.size = base_t->size; | 249 | base_info.size = base_t->size; |
| 253 | break; | 250 | break; |
| 254 | default: | 251 | default: |
| 255 | continue; | 252 | continue; |
| 256 | } | 253 | } |
| 257 | /* iterate over all matching distilled base types */ | 254 | /* iterate over all matching distilled base types */ |
| 258 | for (dist_name_info = search_btf_name_size(&base_name_info, dist_base_info_sorted, | 255 | for (dist_info = search_btf_name_size(&base_info, info, r->nr_dist_base_types); |
| 259 | r->nr_dist_base_types); | 256 | dist_info != NULL && dist_info < info_end && |
| 260 | dist_name_info != NULL; dist_name_info = dist_name_info_next) { | 257 | cmp_btf_name_size(&base_info, dist_info) == 0; |
| 261 | /* Are there more distilled matches to process after | 258 | dist_info++) { |
| 262 | * this one? | 259 | if (!dist_info->id || dist_info->id >= r->nr_dist_base_types) { |
| 263 | */ | ||
| 264 | dist_name_info_next = dist_name_info + 1; | ||
| 265 | if (dist_name_info_next >= dist_base_info_sorted_end || | ||
| 266 | cmp_btf_name_size(&base_name_info, dist_name_info_next)) | ||
| 267 | dist_name_info_next = NULL; | ||
| 268 | |||
| 269 | if (!dist_name_info->id || dist_name_info->id > r->nr_dist_base_types) { | ||
| 270 | pr_warn("base BTF id [%d] maps to invalid distilled base BTF id [%d]\n", | 260 | pr_warn("base BTF id [%d] maps to invalid distilled base BTF id [%d]\n", |
| 271 | id, dist_name_info->id); | 261 | id, dist_info->id); |
| 272 | err = -EINVAL; | 262 | err = -EINVAL; |
| 273 | goto done; | 263 | goto done; |
| 274 | } | 264 | } |
| 275 | dist_t = btf_type_by_id(r->dist_base_btf, dist_name_info->id); | 265 | dist_t = btf_type_by_id(r->dist_base_btf, dist_info->id); |
| 276 | dist_kind = btf_kind(dist_t); | 266 | dist_kind = btf_kind(dist_t); |
| 277 | 267 | ||
| 278 | /* Validate that the found distilled type is compatible. | 268 | /* Validate that the found distilled type is compatible. |
| @@ -319,15 +309,15 @@ static int btf_relocate_map_distilled_base(struct btf_relocate *r) · 40 unmodified lines | |||
| 319 | /* size verification is required for embedded | 309 | /* size verification is required for embedded |
| 320 | * struct/unions. | 310 | * struct/unions. |
| 321 | */ | 311 | */ |
| 322 | if (r->id_map[dist_name_info->id] == BTF_IS_EMBEDDED && | 312 | if (r->id_map[dist_info->id] == BTF_IS_EMBEDDED && |
| 323 | base_t->size != dist_t->size) | 313 | base_t->size != dist_t->size) |
| 324 | continue; | 314 | continue; |
| 325 | break; | 315 | break; |
| 326 | default: | 316 | default: |
| 327 | continue; | 317 | continue; |
| 328 | } | 318 | } |
| 329 | if (r->id_map[dist_name_info->id] && | 319 | if (r->id_map[dist_info->id] && |
| 330 | r->id_map[dist_name_info->id] != BTF_IS_EMBEDDED) { | 320 | r->id_map[dist_info->id] != BTF_IS_EMBEDDED) { |
| 331 | /* we already have a match; this tells us that | 321 | /* we already have a match; this tells us that |
| 332 | * multiple base types of the same name | 322 | * multiple base types of the same name |
| 333 | * have the same size, since for cases where | 323 | * have the same size, since for cases where |
| @@ -337,13 +327,13 @@ static int btf_relocate_map_distilled_base(struct btf_relocate *r) · 3 unmodified lines | |||
| 337 | * to in base BTF, so error out. | 327 | * to in base BTF, so error out. |
| 338 | */ | 328 | */ |
| 339 | pr_warn("distilled base BTF type '%s' [%u], size %u has multiple candidates of the same size (ids [%u, %u]) in base BTF\n", | 329 | pr_warn("distilled base BTF type '%s' [%u], size %u has multiple candidates of the same size (ids [%u, %u]) in base BTF\n", |
| 340 | base_name_info.name, dist_name_info->id, | 330 | base_info.name, dist_info->id, |
| 341 | base_t->size, id, r->id_map[dist_name_info->id]); | 331 | base_t->size, id, r->id_map[dist_info->id]); |
| 342 | err = -EINVAL; | 332 | err = -EINVAL; |
| 343 | goto done; | 333 | goto done; |
| 344 | } | 334 | } |
| 345 | /* map id and name */ | 335 | /* map id and name */ |
| 346 | r->id_map[dist_name_info->id] = id; | 336 | r->id_map[dist_info->id] = id; |
| 347 | r->str_map[dist_t->name_off] = base_t->name_off; | 337 | r->str_map[dist_t->name_off] = base_t->name_off; |
| 348 | } | 338 | } |
| 349 | } | 339 | } |
| @@ -362,7 +352,7 @@ static int btf_relocate_map_distilled_base(struct btf_relocate *r) · 12 unmodified lines | |||
| 362 | } | 352 | } |
| 363 | done: | 353 | done: |
| 364 | free(base_name_cnt); | 354 | free(base_name_cnt); |
| 365 | free(dist_base_info_sorted); | 355 | free(info); |
| 366 | return err; | 356 | return err; |
| 367 | } | 357 | } |
| 368 | 358 | ||