Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

gendwarfksyms: Expand subroutine_type

Add support for expanding DW_TAG_subroutine_type and the parameters
in DW_TAG_formal_parameter. Use this to also expand subprograms.

Example output with --dump-dies:

subprogram (
formal_parameter pointer_type {
const_type {
base_type char byte_size(1) encoding(6)
}
}
)
-> base_type unsigned long byte_size(8) encoding(7)

Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
Reviewed-by: Petr Pavlu <petr.pavlu@suse.com>
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>

authored by

Sami Tolvanen and committed by
Masahiro Yamada
220a0857 06b8b036

+85 -3
+81 -3
scripts/gendwarfksyms/dwarf.c
··· 212 212 DEFINE_PROCESS_UDATA_ATTRIBUTE(byte_size) 213 213 DEFINE_PROCESS_UDATA_ATTRIBUTE(encoding) 214 214 215 + /* Match functions -- die_match_callback_t */ 216 + #define DEFINE_MATCH(type) \ 217 + static bool match_##type##_type(Dwarf_Die *die) \ 218 + { \ 219 + return dwarf_tag(die) == DW_TAG_##type##_type; \ 220 + } 221 + 222 + DEFINE_MATCH(formal_parameter) 223 + 215 224 bool match_all(Dwarf_Die *die) 216 225 { 217 226 return true; ··· 233 224 Dwarf_Die current; 234 225 int res; 235 226 227 + /* Track the first item in lists. */ 228 + if (state) 229 + state->first_list_item = true; 230 + 236 231 res = checkp(dwarf_child(die, &current)); 237 232 while (!res) { 238 233 if (match(&current)) { 239 234 /* <0 = error, 0 = continue, >0 = stop */ 240 235 res = checkp(func(state, cache, &current)); 241 236 if (res) 242 - return res; 237 + goto out; 243 238 } 244 239 245 240 res = checkp(dwarf_siblingof(&current, &current)); 246 241 } 247 242 248 - return 0; 243 + res = 0; 244 + out: 245 + if (state) 246 + state->first_list_item = false; 247 + 248 + return res; 249 249 } 250 250 251 251 static int process_type(struct state *state, struct die *parent, ··· 273 255 /* Compilers can omit DW_AT_type -- print out 'void' to clarify */ 274 256 process(cache, "base_type void"); 275 257 } 258 + 259 + static void process_list_comma(struct state *state, struct die *cache) 260 + { 261 + if (state->first_list_item) { 262 + state->first_list_item = false; 263 + } else { 264 + process(cache, " ,"); 265 + process_linebreak(cache, 0); 266 + } 267 + } 268 + 269 + /* Comma-separated with DW_AT_type */ 270 + static void __process_list_type(struct state *state, struct die *cache, 271 + Dwarf_Die *die, const char *type) 272 + { 273 + const char *name = get_name_attr(die); 274 + 275 + process_list_comma(state, cache); 276 + process(cache, type); 277 + process_type_attr(state, cache, die); 278 + if (name) { 279 + process(cache, " "); 280 + process(cache, name); 281 + } 282 + } 283 + 284 + #define DEFINE_PROCESS_LIST_TYPE(type) \ 285 + static void process_##type##_type(struct state *state, \ 286 + struct die *cache, Dwarf_Die *die) \ 287 + { \ 288 + __process_list_type(state, cache, die, #type " "); \ 289 + } 290 + 291 + DEFINE_PROCESS_LIST_TYPE(formal_parameter) 276 292 277 293 /* Container types with DW_AT_type */ 278 294 static void __process_type(struct state *state, struct die *cache, ··· 341 289 DEFINE_PROCESS_TYPE(shared) 342 290 DEFINE_PROCESS_TYPE(volatile) 343 291 DEFINE_PROCESS_TYPE(typedef) 292 + 293 + static void __process_subroutine_type(struct state *state, struct die *cache, 294 + Dwarf_Die *die, const char *type) 295 + { 296 + process(cache, type); 297 + process(cache, " ("); 298 + process_linebreak(cache, 1); 299 + /* Parameters */ 300 + check(process_die_container(state, cache, die, process_type, 301 + match_formal_parameter_type)); 302 + process_linebreak(cache, -1); 303 + process(cache, ")"); 304 + process_linebreak(cache, 0); 305 + /* Return type */ 306 + process(cache, "-> "); 307 + process_type_attr(state, cache, die); 308 + } 309 + 310 + static void process_subroutine_type(struct state *state, struct die *cache, 311 + Dwarf_Die *die) 312 + { 313 + __process_subroutine_type(state, cache, die, "subroutine_type"); 314 + } 344 315 345 316 static void process_base_type(struct state *state, struct die *cache, 346 317 Dwarf_Die *die) ··· 435 360 PROCESS_TYPE(rvalue_reference) 436 361 PROCESS_TYPE(shared) 437 362 PROCESS_TYPE(volatile) 363 + /* Subtypes */ 364 + PROCESS_TYPE(formal_parameter) 438 365 /* Other types */ 439 366 PROCESS_TYPE(base) 367 + PROCESS_TYPE(subroutine) 440 368 PROCESS_TYPE(typedef) 441 369 default: 442 370 debug("unimplemented type: %x", tag); ··· 469 391 static int __process_subprogram(struct state *state, struct die *cache, 470 392 Dwarf_Die *die) 471 393 { 472 - process(cache, "subprogram"); 394 + __process_subroutine_type(state, cache, die, "subprogram"); 473 395 return 0; 474 396 } 475 397
+4
scripts/gendwarfksyms/gendwarfksyms.h
··· 60 60 #define checkp(expr) __check(expr, __res < 0) 61 61 62 62 /* Consistent aliases (DW_TAG_<type>_type) for DWARF tags */ 63 + #define DW_TAG_formal_parameter_type DW_TAG_formal_parameter 63 64 #define DW_TAG_typedef_type DW_TAG_typedef 64 65 65 66 /* ··· 155 154 struct state { 156 155 struct symbol *sym; 157 156 Dwarf_Die die; 157 + 158 + /* List expansion */ 159 + bool first_list_item; 158 160 }; 159 161 160 162 typedef int (*die_callback_t)(struct state *state, struct die *cache,