@@ -48,6 +48,8 @@ struct btf_dump_type_aux_state {
48
48
__u8 fwd_emitted : 1 ;
49
49
/* whether unique non-duplicate name was already assigned */
50
50
__u8 name_resolved : 1 ;
51
+ /* whether type is referenced from any other type */
52
+ __u8 referenced : 1 ;
51
53
};
52
54
53
55
struct btf_dump {
@@ -173,6 +175,7 @@ void btf_dump__free(struct btf_dump *d)
173
175
free (d );
174
176
}
175
177
178
+ static int btf_dump_mark_referenced (struct btf_dump * d );
176
179
static int btf_dump_order_type (struct btf_dump * d , __u32 id , bool through_ptr );
177
180
static void btf_dump_emit_type (struct btf_dump * d , __u32 id , __u32 cont_id );
178
181
@@ -213,6 +216,11 @@ int btf_dump__dump_type(struct btf_dump *d, __u32 id)
213
216
/* VOID is special */
214
217
d -> type_states [0 ].order_state = ORDERED ;
215
218
d -> type_states [0 ].emit_state = EMITTED ;
219
+
220
+ /* eagerly determine referenced types for anon enums */
221
+ err = btf_dump_mark_referenced (d );
222
+ if (err )
223
+ return err ;
216
224
}
217
225
218
226
d -> emit_queue_cnt = 0 ;
@@ -226,6 +234,79 @@ int btf_dump__dump_type(struct btf_dump *d, __u32 id)
226
234
return 0 ;
227
235
}
228
236
237
+ /*
238
+ * Mark all types that are referenced from any other type. This is used to
239
+ * determine top-level anonymous enums that need to be emitted as an
240
+ * independent type declarations.
241
+ * Anonymous enums come in two flavors: either embedded in a struct's field
242
+ * definition, in which case they have to be declared inline as part of field
243
+ * type declaration; or as a top-level anonymous enum, typically used for
244
+ * declaring global constants. It's impossible to distinguish between two
245
+ * without knowning whether given enum type was referenced from other type:
246
+ * top-level anonymous enum won't be referenced by anything, while embedded
247
+ * one will.
248
+ */
249
+ static int btf_dump_mark_referenced (struct btf_dump * d )
250
+ {
251
+ int i , j , n = btf__get_nr_types (d -> btf );
252
+ const struct btf_type * t ;
253
+ __u16 vlen ;
254
+
255
+ for (i = 1 ; i <= n ; i ++ ) {
256
+ t = btf__type_by_id (d -> btf , i );
257
+ vlen = btf_vlen (t );
258
+
259
+ switch (btf_kind (t )) {
260
+ case BTF_KIND_INT :
261
+ case BTF_KIND_ENUM :
262
+ case BTF_KIND_FWD :
263
+ break ;
264
+
265
+ case BTF_KIND_VOLATILE :
266
+ case BTF_KIND_CONST :
267
+ case BTF_KIND_RESTRICT :
268
+ case BTF_KIND_PTR :
269
+ case BTF_KIND_TYPEDEF :
270
+ case BTF_KIND_FUNC :
271
+ case BTF_KIND_VAR :
272
+ d -> type_states [t -> type ].referenced = 1 ;
273
+ break ;
274
+
275
+ case BTF_KIND_ARRAY : {
276
+ const struct btf_array * a = btf_array (t );
277
+
278
+ d -> type_states [a -> index_type ].referenced = 1 ;
279
+ d -> type_states [a -> type ].referenced = 1 ;
280
+ break ;
281
+ }
282
+ case BTF_KIND_STRUCT :
283
+ case BTF_KIND_UNION : {
284
+ const struct btf_member * m = btf_members (t );
285
+
286
+ for (j = 0 ; j < vlen ; j ++ , m ++ )
287
+ d -> type_states [m -> type ].referenced = 1 ;
288
+ break ;
289
+ }
290
+ case BTF_KIND_FUNC_PROTO : {
291
+ const struct btf_param * p = btf_params (t );
292
+
293
+ for (j = 0 ; j < vlen ; j ++ , p ++ )
294
+ d -> type_states [p -> type ].referenced = 1 ;
295
+ break ;
296
+ }
297
+ case BTF_KIND_DATASEC : {
298
+ const struct btf_var_secinfo * v = btf_var_secinfos (t );
299
+
300
+ for (j = 0 ; j < vlen ; j ++ , v ++ )
301
+ d -> type_states [v -> type ].referenced = 1 ;
302
+ break ;
303
+ }
304
+ default :
305
+ return - EINVAL ;
306
+ }
307
+ }
308
+ return 0 ;
309
+ }
229
310
static int btf_dump_add_emit_queue_id (struct btf_dump * d , __u32 id )
230
311
{
231
312
__u32 * new_queue ;
@@ -395,7 +476,12 @@ static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr)
395
476
}
396
477
case BTF_KIND_ENUM :
397
478
case BTF_KIND_FWD :
398
- if (t -> name_off != 0 ) {
479
+ /*
480
+ * non-anonymous or non-referenced enums are top-level
481
+ * declarations and should be emitted. Same logic can be
482
+ * applied to FWDs, it won't hurt anyways.
483
+ */
484
+ if (t -> name_off != 0 || !tstate -> referenced ) {
399
485
err = btf_dump_add_emit_queue_id (d , id );
400
486
if (err )
401
487
return err ;
@@ -536,11 +622,6 @@ static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id)
536
622
t = btf__type_by_id (d -> btf , id );
537
623
kind = btf_kind (t );
538
624
539
- if (top_level_def && t -> name_off == 0 ) {
540
- pr_warning ("unexpected nameless definition, id:[%u]\n" , id );
541
- return ;
542
- }
543
-
544
625
if (tstate -> emit_state == EMITTING ) {
545
626
if (tstate -> fwd_emitted )
546
627
return ;
0 commit comments