@@ -60,11 +60,14 @@ struct btf_dump {
60
60
struct btf_dump_opts opts ;
61
61
int ptr_sz ;
62
62
bool strip_mods ;
63
+ int last_id ;
63
64
64
65
/* per-type auxiliary state */
65
66
struct btf_dump_type_aux_state * type_states ;
67
+ size_t type_states_cap ;
66
68
/* per-type optional cached unique name, must be freed, if present */
67
69
const char * * cached_names ;
70
+ size_t cached_names_cap ;
68
71
69
72
/* topo-sorted list of dependent type definitions */
70
73
__u32 * emit_queue ;
@@ -113,6 +116,7 @@ static void btf_dump_printf(const struct btf_dump *d, const char *fmt, ...)
113
116
}
114
117
115
118
static int btf_dump_mark_referenced (struct btf_dump * d );
119
+ static int btf_dump_resize (struct btf_dump * d );
116
120
117
121
struct btf_dump * btf_dump__new (const struct btf * btf ,
118
122
const struct btf_ext * btf_ext ,
@@ -144,25 +148,8 @@ struct btf_dump *btf_dump__new(const struct btf *btf,
144
148
d -> ident_names = NULL ;
145
149
goto err ;
146
150
}
147
- d -> type_states = calloc (1 + btf__get_nr_types (d -> btf ),
148
- sizeof (d -> type_states [0 ]));
149
- if (!d -> type_states ) {
150
- err = - ENOMEM ;
151
- goto err ;
152
- }
153
- d -> cached_names = calloc (1 + btf__get_nr_types (d -> btf ),
154
- sizeof (d -> cached_names [0 ]));
155
- if (!d -> cached_names ) {
156
- err = - ENOMEM ;
157
- goto err ;
158
- }
159
151
160
- /* VOID is special */
161
- d -> type_states [0 ].order_state = ORDERED ;
162
- d -> type_states [0 ].emit_state = EMITTED ;
163
-
164
- /* eagerly determine referenced types for anon enums */
165
- err = btf_dump_mark_referenced (d );
152
+ err = btf_dump_resize (d );
166
153
if (err )
167
154
goto err ;
168
155
@@ -172,17 +159,46 @@ struct btf_dump *btf_dump__new(const struct btf *btf,
172
159
return ERR_PTR (err );
173
160
}
174
161
162
+ static int btf_dump_resize (struct btf_dump * d )
163
+ {
164
+ int err , last_id = btf__get_nr_types (d -> btf );
165
+
166
+ if (last_id <= d -> last_id )
167
+ return 0 ;
168
+
169
+ if (btf_ensure_mem ((void * * )& d -> type_states , & d -> type_states_cap ,
170
+ sizeof (* d -> type_states ), last_id + 1 ))
171
+ return - ENOMEM ;
172
+ if (btf_ensure_mem ((void * * )& d -> cached_names , & d -> cached_names_cap ,
173
+ sizeof (* d -> cached_names ), last_id + 1 ))
174
+ return - ENOMEM ;
175
+
176
+ if (d -> last_id == 0 ) {
177
+ /* VOID is special */
178
+ d -> type_states [0 ].order_state = ORDERED ;
179
+ d -> type_states [0 ].emit_state = EMITTED ;
180
+ }
181
+
182
+ /* eagerly determine referenced types for anon enums */
183
+ err = btf_dump_mark_referenced (d );
184
+ if (err )
185
+ return err ;
186
+
187
+ d -> last_id = last_id ;
188
+ return 0 ;
189
+ }
190
+
175
191
void btf_dump__free (struct btf_dump * d )
176
192
{
177
- int i , cnt ;
193
+ int i ;
178
194
179
195
if (IS_ERR_OR_NULL (d ))
180
196
return ;
181
197
182
198
free (d -> type_states );
183
199
if (d -> cached_names ) {
184
200
/* any set cached name is owned by us and should be freed */
185
- for (i = 0 , cnt = btf__get_nr_types ( d -> btf ) ; i <= cnt ; i ++ ) {
201
+ for (i = 0 ; i <= d -> last_id ; i ++ ) {
186
202
if (d -> cached_names [i ])
187
203
free ((void * )d -> cached_names [i ]);
188
204
}
@@ -222,6 +238,10 @@ int btf_dump__dump_type(struct btf_dump *d, __u32 id)
222
238
if (id > btf__get_nr_types (d -> btf ))
223
239
return - EINVAL ;
224
240
241
+ err = btf_dump_resize (d );
242
+ if (err )
243
+ return err ;
244
+
225
245
d -> emit_queue_cnt = 0 ;
226
246
err = btf_dump_order_type (d , id , false);
227
247
if (err < 0 )
@@ -251,7 +271,7 @@ static int btf_dump_mark_referenced(struct btf_dump *d)
251
271
const struct btf_type * t ;
252
272
__u16 vlen ;
253
273
254
- for (i = 1 ; i <= n ; i ++ ) {
274
+ for (i = d -> last_id + 1 ; i <= n ; i ++ ) {
255
275
t = btf__type_by_id (d -> btf , i );
256
276
vlen = btf_vlen (t );
257
277
@@ -306,6 +326,7 @@ static int btf_dump_mark_referenced(struct btf_dump *d)
306
326
}
307
327
return 0 ;
308
328
}
329
+
309
330
static int btf_dump_add_emit_queue_id (struct btf_dump * d , __u32 id )
310
331
{
311
332
__u32 * new_queue ;
@@ -1049,11 +1070,15 @@ int btf_dump__emit_type_decl(struct btf_dump *d, __u32 id,
1049
1070
const struct btf_dump_emit_type_decl_opts * opts )
1050
1071
{
1051
1072
const char * fname ;
1052
- int lvl ;
1073
+ int lvl , err ;
1053
1074
1054
1075
if (!OPTS_VALID (opts , btf_dump_emit_type_decl_opts ))
1055
1076
return - EINVAL ;
1056
1077
1078
+ err = btf_dump_resize (d );
1079
+ if (err )
1080
+ return - EINVAL ;
1081
+
1057
1082
fname = OPTS_GET (opts , field_name , "" );
1058
1083
lvl = OPTS_GET (opts , indent_level , 0 );
1059
1084
d -> strip_mods = OPTS_GET (opts , strip_mods , false);
0 commit comments