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 | 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 | 164 | struct btf_type *base_t, *dist_t; |
| 165 | 165 | __u8 *base_name_cnt = NULL; |
| 166 | 166 | int err = 0; |
| @@ -169,26 +169,24 @@ static int btf_relocate_map_distilled_base(struct btf_relocate *r) · 2 unmodified lines | ||
| 169 | 169 | /* generate a sort index array of name/type ids sorted by name for |
| 170 | 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)); | |
| 173 | − if (!dist_base_info_sorted) { | |
| 172 | + info = calloc(r->nr_dist_base_types, sizeof(*info)); | |
| 173 | + if (!info) { | |
| 174 | 174 | err = -ENOMEM; |
| 175 | 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 | 178 | for (id = 0; id < r->nr_dist_base_types; id++) { |
| 179 | 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, | |
| 181 | − dist_t->name_off); | |
| 182 | − dist_base_info_sorted[id].id = id; | |
| 183 | − dist_base_info_sorted[id].size = dist_t->size; | |
| 184 | − dist_base_info_sorted[id].needs_size = true; | |
| 180 | + info[id].name = btf__name_by_offset(r->dist_base_btf, dist_t->name_off); | |
| 181 | + info[id].id = id; | |
| 182 | + info[id].size = dist_t->size; | |
| 183 | + info[id].needs_size = true; | |
| 185 | 184 | } |
| 186 | − qsort(dist_base_info_sorted, r->nr_dist_base_types, sizeof(*dist_base_info_sorted), | |
| 187 | − cmp_btf_name_size); | |
| 185 | + qsort(info, r->nr_dist_base_types, sizeof(*info), cmp_btf_name_size); | |
| 188 | 186 | |
| 189 | 187 | /* Mark distilled base struct/union members of split BTF structs/unions |
| 190 | 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 | 190 | * struct/union in the split type is invalid. |
| 193 | 191 | */ |
| 194 | 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 | 215 | /* Now search base BTF for matching distilled base BTF types. */ |
| 218 | 216 | for (id = 1; id < r->nr_base_types; id++) { |
| 219 | − struct btf_name_info *dist_name_info, *dist_name_info_next = NULL; | |
| 220 | − struct btf_name_info base_name_info = {}; | |
| 217 | + struct btf_name_info *dist_info, base_info = {}; | |
| 221 | 218 | int dist_kind, base_kind; |
| 222 | 219 | |
| 223 | 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 | 222 | if (!base_t->name_off) |
| 226 | 223 | continue; |
| 227 | 224 | base_kind = btf_kind(base_t); |
| 228 | − base_name_info.id = id; | |
| 229 | − base_name_info.name = btf__name_by_offset(r->base_btf, base_t->name_off); | |
| 225 | + base_info.id = id; | |
| 226 | + base_info.name = btf__name_by_offset(r->base_btf, base_t->name_off); | |
| 230 | 227 | switch (base_kind) { |
| 231 | 228 | case BTF_KIND_INT: |
| 232 | 229 | case BTF_KIND_FLOAT: |
| 233 | 230 | case BTF_KIND_ENUM: |
| 234 | 231 | case BTF_KIND_ENUM64: |
| 235 | 232 | /* These types should match both name and size */ |
| 236 | − base_name_info.needs_size = true; | |
| 237 | − base_name_info.size = base_t->size; | |
| 233 | + base_info.needs_size = true; | |
| 234 | + base_info.size = base_t->size; | |
| 238 | 235 | break; |
| 239 | 236 | case BTF_KIND_FWD: |
| 240 | 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 | 245 | * unless corresponding _base_ types to match them are |
| 249 | 246 | * missing. |
| 250 | 247 | */ |
| 251 | − base_name_info.needs_size = base_name_cnt[base_t->name_off] > 1; | |
| 252 | − base_name_info.size = base_t->size; | |
| 248 | + base_info.needs_size = base_name_cnt[base_t->name_off] > 1; | |
| 249 | + base_info.size = base_t->size; | |
| 253 | 250 | break; |
| 254 | 251 | default: |
| 255 | 252 | continue; |
| 256 | 253 | } |
| 257 | 254 | /* iterate over all matching distilled base types */ |
| 258 | − for (dist_name_info = search_btf_name_size(&base_name_info, dist_base_info_sorted, | |
| 259 | − r->nr_dist_base_types); | |
| 260 | − dist_name_info != NULL; dist_name_info = dist_name_info_next) { | |
| 261 | − /* Are there more distilled matches to process after | |
| 262 | − * this one? | |
| 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) { | |
| 255 | + for (dist_info = search_btf_name_size(&base_info, info, r->nr_dist_base_types); | |
| 256 | + dist_info != NULL && dist_info < info_end && | |
| 257 | + cmp_btf_name_size(&base_info, dist_info) == 0; | |
| 258 | + dist_info++) { | |
| 259 | + if (!dist_info->id || dist_info->id >= r->nr_dist_base_types) { | |
| 270 | 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 | 262 | err = -EINVAL; |
| 273 | 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 | 266 | dist_kind = btf_kind(dist_t); |
| 277 | 267 | |
| 278 | 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 | 309 | /* size verification is required for embedded |
| 320 | 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 | 313 | base_t->size != dist_t->size) |
| 324 | 314 | continue; |
| 325 | 315 | break; |
| 326 | 316 | default: |
| 327 | 317 | continue; |
| 328 | 318 | } |
| 329 | − if (r->id_map[dist_name_info->id] && | |
| 330 | − r->id_map[dist_name_info->id] != BTF_IS_EMBEDDED) { | |
| 319 | + if (r->id_map[dist_info->id] && | |
| 320 | + r->id_map[dist_info->id] != BTF_IS_EMBEDDED) { | |
| 331 | 321 | /* we already have a match; this tells us that |
| 332 | 322 | * multiple base types of the same name |
| 333 | 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 | 327 | * to in base BTF, so error out. |
| 338 | 328 | */ |
| 339 | 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, | |
| 341 | − base_t->size, id, r->id_map[dist_name_info->id]); | |
| 330 | + base_info.name, dist_info->id, | |
| 331 | + base_t->size, id, r->id_map[dist_info->id]); | |
| 342 | 332 | err = -EINVAL; |
| 343 | 333 | goto done; |
| 344 | 334 | } |
| 345 | 335 | /* map id and name */ |
| 346 | − r->id_map[dist_name_info->id] = id; | |
| 336 | + r->id_map[dist_info->id] = id; | |
| 347 | 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 | 353 | done: |
| 364 | 354 | free(base_name_cnt); |
| 365 | − free(dist_base_info_sorted); | |
| 355 | + free(info); | |
| 366 | 356 | return err; |
| 367 | 357 | } |
| 368 | 358 | |