Skip to content

Commit 4acda8e

Browse files
committed
scripts/sorttable: Get start/stop_mcount_loc from ELF file directly
The get_mcount_loc() does a cheesy trick to find the start_mcount_loc and stop_mcount_loc values. That trick is: file_start = popen(" grep start_mcount System.map | awk '{print $1}' ", "r"); and file_stop = popen(" grep stop_mcount System.map | awk '{print $1}' ", "r"); Those values are stored in the Elf symbol table. Use that to capture those values. Using the symbol table is more efficient and more robust. The above could fail if another variable had "start_mcount" or "stop_mcount" as part of its name. Cc: bpf <bpf@vger.kernel.org> Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Masahiro Yamada <masahiroy@kernel.org> Cc: Nathan Chancellor <nathan@kernel.org> Cc: Nicolas Schier <nicolas@fjasle.eu> Cc: Zheng Yejian <zhengyejian1@huawei.com> Cc: Martin Kelly <martin.kelly@crowdstrike.com> Cc: Christophe Leroy <christophe.leroy@csgroup.eu> Cc: Josh Poimboeuf <jpoimboe@redhat.com> Link: https://lore.kernel.org/20250105162346.817157047@goodmis.org Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
1 parent 58d8767 commit 4acda8e

File tree

1 file changed

+45
-50
lines changed

1 file changed

+45
-50
lines changed

scripts/sorttable.c

Lines changed: 45 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -472,42 +472,41 @@ static void *sort_mcount_loc(void *arg)
472472
}
473473

474474
/* Get the address of __start_mcount_loc and __stop_mcount_loc in System.map */
475-
static void get_mcount_loc(uint64_t *_start, uint64_t *_stop)
475+
static void get_mcount_loc(struct elf_mcount_loc *emloc, Elf_Shdr *symtab_sec,
476+
const char *strtab)
476477
{
477-
FILE *file_start, *file_stop;
478-
char start_buff[20];
479-
char stop_buff[20];
480-
int len = 0;
478+
Elf_Sym *sym, *end_sym;
479+
int symentsize = shdr_entsize(symtab_sec);
480+
int found = 0;
481+
482+
sym = (void *)emloc->ehdr + shdr_offset(symtab_sec);
483+
end_sym = (void *)sym + shdr_size(symtab_sec);
484+
485+
while (sym < end_sym) {
486+
if (!strcmp(strtab + sym_name(sym), "__start_mcount_loc")) {
487+
emloc->start_mcount_loc = sym_value(sym);
488+
if (++found == 2)
489+
break;
490+
} else if (!strcmp(strtab + sym_name(sym), "__stop_mcount_loc")) {
491+
emloc->stop_mcount_loc = sym_value(sym);
492+
if (++found == 2)
493+
break;
494+
}
495+
sym = (void *)sym + symentsize;
496+
}
481497

482-
file_start = popen(" grep start_mcount System.map | awk '{print $1}' ", "r");
483-
if (!file_start) {
498+
if (!emloc->start_mcount_loc) {
484499
fprintf(stderr, "get start_mcount_loc error!");
485500
return;
486501
}
487502

488-
file_stop = popen(" grep stop_mcount System.map | awk '{print $1}' ", "r");
489-
if (!file_stop) {
503+
if (!emloc->stop_mcount_loc) {
490504
fprintf(stderr, "get stop_mcount_loc error!");
491-
pclose(file_start);
492505
return;
493506
}
494-
495-
while (fgets(start_buff, sizeof(start_buff), file_start) != NULL) {
496-
len = strlen(start_buff);
497-
start_buff[len - 1] = '\0';
498-
}
499-
*_start = strtoul(start_buff, NULL, 16);
500-
501-
while (fgets(stop_buff, sizeof(stop_buff), file_stop) != NULL) {
502-
len = strlen(stop_buff);
503-
stop_buff[len - 1] = '\0';
504-
}
505-
*_stop = strtoul(stop_buff, NULL, 16);
506-
507-
pclose(file_start);
508-
pclose(file_stop);
509507
}
510508
#endif
509+
511510
static int do_sort(Elf_Ehdr *ehdr,
512511
char const *const fname,
513512
table_sort_t custom_sort)
@@ -538,8 +537,6 @@ static int do_sort(Elf_Ehdr *ehdr,
538537
unsigned int shstrndx;
539538
#ifdef MCOUNT_SORT_ENABLED
540539
struct elf_mcount_loc mstruct = {0};
541-
uint64_t _start_mcount_loc = 0;
542-
uint64_t _stop_mcount_loc = 0;
543540
#endif
544541
#ifdef UNWINDER_ORC_ENABLED
545542
unsigned int orc_ip_size = 0;
@@ -577,13 +574,8 @@ static int do_sort(Elf_Ehdr *ehdr,
577574

578575
#ifdef MCOUNT_SORT_ENABLED
579576
/* locate the .init.data section in vmlinux */
580-
if (!strcmp(secstrings + idx, ".init.data")) {
581-
get_mcount_loc(&_start_mcount_loc, &_stop_mcount_loc);
582-
mstruct.ehdr = ehdr;
577+
if (!strcmp(secstrings + idx, ".init.data"))
583578
mstruct.init_data_sec = shdr;
584-
mstruct.start_mcount_loc = _start_mcount_loc;
585-
mstruct.stop_mcount_loc = _stop_mcount_loc;
586-
}
587579
#endif
588580

589581
#ifdef UNWINDER_ORC_ENABLED
@@ -627,23 +619,6 @@ static int do_sort(Elf_Ehdr *ehdr,
627619
goto out;
628620
}
629621
#endif
630-
631-
#ifdef MCOUNT_SORT_ENABLED
632-
if (!mstruct.init_data_sec || !_start_mcount_loc || !_stop_mcount_loc) {
633-
fprintf(stderr,
634-
"incomplete mcount's sort in file: %s\n",
635-
fname);
636-
goto out;
637-
}
638-
639-
/* create thread to sort mcount_loc concurrently */
640-
if (pthread_create(&mcount_sort_thread, NULL, &sort_mcount_loc, &mstruct)) {
641-
fprintf(stderr,
642-
"pthread_create mcount_sort_thread failed '%s': %s\n",
643-
strerror(errno), fname);
644-
goto out;
645-
}
646-
#endif
647622
if (!extab_sec) {
648623
fprintf(stderr, "no __ex_table in file: %s\n", fname);
649624
goto out;
@@ -663,6 +638,26 @@ static int do_sort(Elf_Ehdr *ehdr,
663638
strtab = (const char *)ehdr + shdr_offset(strtab_sec);
664639
symtab = (const Elf_Sym *)((const char *)ehdr + shdr_offset(symtab_sec));
665640

641+
#ifdef MCOUNT_SORT_ENABLED
642+
mstruct.ehdr = ehdr;
643+
get_mcount_loc(&mstruct, symtab_sec, strtab);
644+
645+
if (!mstruct.init_data_sec || !mstruct.start_mcount_loc || !mstruct.stop_mcount_loc) {
646+
fprintf(stderr,
647+
"incomplete mcount's sort in file: %s\n",
648+
fname);
649+
goto out;
650+
}
651+
652+
/* create thread to sort mcount_loc concurrently */
653+
if (pthread_create(&mcount_sort_thread, NULL, &sort_mcount_loc, &mstruct)) {
654+
fprintf(stderr,
655+
"pthread_create mcount_sort_thread failed '%s': %s\n",
656+
strerror(errno), fname);
657+
goto out;
658+
}
659+
#endif
660+
666661
if (custom_sort) {
667662
custom_sort(extab_image, shdr_size(extab_sec));
668663
} else {

0 commit comments

Comments
 (0)