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.

objtool/klp: Use sym->demangled_name for symbol_name hash

For klp-build with LTO, it is necessary to correlate demangled symbols,
e.g., correlate foo.llvm.<num 1> and foo.llvm.<num 2>. However, these two
symbols do not have the same str_hash(name). To be able to correlate the
two symbols, calculate hash based on demanged_name, so that these two
symbols have the same hash.

No functional changes intended.

Signed-off-by: Song Liu <song@kernel.org>
Link: https://patch.msgid.link/20260305231531.3847295-4-song@kernel.org
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>

authored by

Song Liu and committed by
Josh Poimboeuf
0b8fc6ad a3f28d20

+40 -18
+40 -18
tools/objtool/elf.c
··· 26 26 #include <objtool/elf.h> 27 27 #include <objtool/warn.h> 28 28 29 + static ssize_t demangled_name_len(const char *name); 30 + 29 31 static inline u32 str_hash(const char *str) 30 32 { 31 33 return jhash(str, strlen(str), 0); 34 + } 35 + 36 + static inline u32 str_hash_demangled(const char *str) 37 + { 38 + return jhash(str, demangled_name_len(str), 0); 32 39 } 33 40 34 41 #define __elf_table(name) (elf->name##_hash) ··· 301 294 { 302 295 struct symbol *sym; 303 296 304 - elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash(name)) { 297 + elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash_demangled(name)) { 305 298 if (sym->bind == STB_LOCAL && sym->file == file && 306 299 !strcmp(sym->name, name)) { 307 300 return sym; ··· 315 308 { 316 309 struct symbol *sym; 317 310 318 - elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash(name)) { 311 + elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash_demangled(name)) { 319 312 if (!strcmp(sym->name, name) && !is_local_sym(sym)) 320 313 return sym; 321 314 } ··· 449 442 } 450 443 451 444 /* 445 + * Returns desired length of the demangled name. 446 + * If name doesn't need demangling, return strlen(name). 447 + */ 448 + static ssize_t demangled_name_len(const char *name) 449 + { 450 + ssize_t idx; 451 + 452 + if (!strstarts(name, "__UNIQUE_ID_") && !strchr(name, '.')) 453 + return strlen(name); 454 + 455 + for (idx = strlen(name) - 1; idx >= 0; idx--) { 456 + char c = name[idx]; 457 + 458 + if (!isdigit(c) && c != '.' && c != '_') 459 + break; 460 + } 461 + if (idx <= 0) 462 + return strlen(name); 463 + return idx + 1; 464 + } 465 + 466 + /* 452 467 * Remove number suffix of a symbol. 453 468 * 454 469 * Specifically, remove trailing numbers for "__UNIQUE_ID_" symbols and ··· 486 457 static const char *demangle_name(struct symbol *sym) 487 458 { 488 459 char *str; 460 + ssize_t len; 489 461 490 462 if (!is_local_sym(sym)) 491 463 return sym->name; ··· 494 464 if (!is_func_sym(sym) && !is_object_sym(sym)) 495 465 return sym->name; 496 466 497 - if (!strstarts(sym->name, "__UNIQUE_ID_") && !strchr(sym->name, '.')) 467 + len = demangled_name_len(sym->name); 468 + if (len == strlen(sym->name)) 498 469 return sym->name; 499 470 500 - str = strdup(sym->name); 471 + str = strndup(sym->name, len); 501 472 if (!str) { 502 473 ERROR_GLIBC("strdup"); 503 474 return NULL; 504 - } 505 - 506 - for (int i = strlen(str) - 1; i >= 0; i--) { 507 - char c = str[i]; 508 - 509 - if (!isdigit(c) && c != '.' && c != '_') { 510 - str[i + 1] = '\0'; 511 - break; 512 - } 513 475 } 514 476 515 477 return str; ··· 539 517 entry = &sym->sec->symbol_list; 540 518 list_add(&sym->list, entry); 541 519 520 + sym->demangled_name = demangle_name(sym); 521 + if (!sym->demangled_name) 522 + return -1; 523 + 542 524 list_add_tail(&sym->global_list, &elf->symbols); 543 525 elf_hash_add(symbol, &sym->hash, sym->idx); 544 - elf_hash_add(symbol_name, &sym->name_hash, str_hash(sym->name)); 526 + elf_hash_add(symbol_name, &sym->name_hash, str_hash(sym->demangled_name)); 545 527 546 528 if (is_func_sym(sym) && 547 529 (strstarts(sym->name, "__pfx_") || ··· 568 542 } 569 543 570 544 sym->pfunc = sym->cfunc = sym; 571 - 572 - sym->demangled_name = demangle_name(sym); 573 - if (!sym->demangled_name) 574 - return -1; 575 545 576 546 return 0; 577 547 }