linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] perf tools: Resolve symbols against debug file first
@ 2021-01-13  8:01 Jiri Slaby
  2021-01-13 10:46 ` Jiri Olsa
  0 siblings, 1 reply; 9+ messages in thread
From: Jiri Slaby @ 2021-01-13  8:01 UTC (permalink / raw)
  To: acme
  Cc: linux-kernel, Jiri Slaby, Peter Zijlstra, Ingo Molnar,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim

With LTO, there are symbols like these:
/usr/lib/debug/usr/lib64/libantlr4-runtime.so.4.8-4.8-1.4.x86_64.debug
 10305: 0000000000955fa4     0 NOTYPE  LOCAL  DEFAULT   29 Predicate.cpp.2bc410e7

This comes from a runtime/debug split done by the standard way:
objcopy --only-keep-debug $runtime $debug
objcopy --add-gnu-debuglink=$debugfn -R .comment -R .GCC.command.line --strip-all $runtime

perf currently cannot resolve such symbols (relicts of LTO), as section
29 exists only in the debug file (29 is .debug_info). And perf resolves
symbols only against runtime file. This results in all symbols from such
a library being unresolved:
     0.38%  main2    libantlr4-runtime.so.4.8  [.] 0x00000000000671e0

So try resolving against the debug file first. And only if it fails (the
section has NOBITS set), try runtime file. We can do this, as "objcopy
--only-keep-debug" per documentation preserves all sections, but clears
data of some of them (the runtime ones) and marks them as NOBITS.

The correct result is now:
     0.38%  main2    libantlr4-runtime.so.4.8  [.] antlr4::IntStream::~IntStream

Note that these LTO symbols are properly skipped anyway as they belong
neither to *text* nor to *data* (is_label && !elf_sec__filter(&shdr,
secstrs) is true).

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/util/symbol-elf.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index f3577f7d72fe..a31b716fa61c 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -1226,12 +1226,20 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
 		if (sym.st_shndx == SHN_ABS)
 			continue;
 
-		sec = elf_getscn(runtime_ss->elf, sym.st_shndx);
+		sec = elf_getscn(syms_ss->elf, sym.st_shndx);
 		if (!sec)
 			goto out_elf_end;
 
 		gelf_getshdr(sec, &shdr);
 
+		if (shdr.sh_type == SHT_NOBITS) {
+			sec = elf_getscn(runtime_ss->elf, sym.st_shndx);
+			if (!sec)
+				goto out_elf_end;
+
+			gelf_getshdr(sec, &shdr);
+		}
+
 		if (is_label && !elf_sec__filter(&shdr, secstrs))
 			continue;
 
-- 
2.30.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH] perf tools: Resolve symbols against debug file first
  2021-01-13  8:01 [PATCH] perf tools: Resolve symbols against debug file first Jiri Slaby
@ 2021-01-13 10:46 ` Jiri Olsa
  2021-01-13 11:43   ` Jiri Slaby
  2021-01-28 10:43   ` Jiri Slaby
  0 siblings, 2 replies; 9+ messages in thread
From: Jiri Olsa @ 2021-01-13 10:46 UTC (permalink / raw)
  To: Jiri Slaby
  Cc: acme, linux-kernel, Peter Zijlstra, Ingo Molnar, Mark Rutland,
	Alexander Shishkin, Namhyung Kim

On Wed, Jan 13, 2021 at 09:01:28AM +0100, Jiri Slaby wrote:
> With LTO, there are symbols like these:
> /usr/lib/debug/usr/lib64/libantlr4-runtime.so.4.8-4.8-1.4.x86_64.debug
>  10305: 0000000000955fa4     0 NOTYPE  LOCAL  DEFAULT   29 Predicate.cpp.2bc410e7
> 
> This comes from a runtime/debug split done by the standard way:
> objcopy --only-keep-debug $runtime $debug
> objcopy --add-gnu-debuglink=$debugfn -R .comment -R .GCC.command.line --strip-all $runtime
> 
> perf currently cannot resolve such symbols (relicts of LTO), as section
> 29 exists only in the debug file (29 is .debug_info). And perf resolves
> symbols only against runtime file. This results in all symbols from such
> a library being unresolved:
>      0.38%  main2    libantlr4-runtime.so.4.8  [.] 0x00000000000671e0
> 
> So try resolving against the debug file first. And only if it fails (the
> section has NOBITS set), try runtime file. We can do this, as "objcopy
> --only-keep-debug" per documentation preserves all sections, but clears
> data of some of them (the runtime ones) and marks them as NOBITS.
> 
> The correct result is now:
>      0.38%  main2    libantlr4-runtime.so.4.8  [.] antlr4::IntStream::~IntStream
> 
> Note that these LTO symbols are properly skipped anyway as they belong
> neither to *text* nor to *data* (is_label && !elf_sec__filter(&shdr,
> secstrs) is true).
> 
> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
> Cc: Jiri Olsa <jolsa@redhat.com>
> Cc: Namhyung Kim <namhyung@kernel.org>
> ---
>  tools/perf/util/symbol-elf.c | 10 +++++++++-
>  1 file changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
> index f3577f7d72fe..a31b716fa61c 100644
> --- a/tools/perf/util/symbol-elf.c
> +++ b/tools/perf/util/symbol-elf.c
> @@ -1226,12 +1226,20 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
>  		if (sym.st_shndx == SHN_ABS)
>  			continue;
>  
> -		sec = elf_getscn(runtime_ss->elf, sym.st_shndx);
> +		sec = elf_getscn(syms_ss->elf, sym.st_shndx);
>  		if (!sec)
>  			goto out_elf_end;

we iterate symbols from syms_ss, so the fix seems to be correct
to call elf_getscn on syms_ss, not on runtime_ss as we do now

I'd think this worked only when runtime_ss == syms_ss

>  
>  		gelf_getshdr(sec, &shdr);
>  
> +		if (shdr.sh_type == SHT_NOBITS) {
> +			sec = elf_getscn(runtime_ss->elf, sym.st_shndx);
> +			if (!sec)
> +				goto out_elf_end;
> +
> +			gelf_getshdr(sec, &shdr);
> +		}

is that fallback necessary? the symbol is from syms_ss

Namhyung, any idea?

thanks,
jirka


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] perf tools: Resolve symbols against debug file first
  2021-01-13 10:46 ` Jiri Olsa
@ 2021-01-13 11:43   ` Jiri Slaby
  2021-01-14  4:54     ` Namhyung Kim
  2021-01-28 10:43   ` Jiri Slaby
  1 sibling, 1 reply; 9+ messages in thread
From: Jiri Slaby @ 2021-01-13 11:43 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: acme, linux-kernel, Peter Zijlstra, Ingo Molnar, Mark Rutland,
	Alexander Shishkin, Namhyung Kim

On 13. 01. 21, 11:46, Jiri Olsa wrote:
> On Wed, Jan 13, 2021 at 09:01:28AM +0100, Jiri Slaby wrote:
>> With LTO, there are symbols like these:
>> /usr/lib/debug/usr/lib64/libantlr4-runtime.so.4.8-4.8-1.4.x86_64.debug
>>   10305: 0000000000955fa4     0 NOTYPE  LOCAL  DEFAULT   29 Predicate.cpp.2bc410e7
>>
>> This comes from a runtime/debug split done by the standard way:
>> objcopy --only-keep-debug $runtime $debug
>> objcopy --add-gnu-debuglink=$debugfn -R .comment -R .GCC.command.line --strip-all $runtime
>>
>> perf currently cannot resolve such symbols (relicts of LTO), as section
>> 29 exists only in the debug file (29 is .debug_info). And perf resolves
>> symbols only against runtime file. This results in all symbols from such
>> a library being unresolved:
>>       0.38%  main2    libantlr4-runtime.so.4.8  [.] 0x00000000000671e0
>>
>> So try resolving against the debug file first. And only if it fails (the
>> section has NOBITS set), try runtime file. We can do this, as "objcopy
>> --only-keep-debug" per documentation preserves all sections, but clears
>> data of some of them (the runtime ones) and marks them as NOBITS.
>>
>> The correct result is now:
>>       0.38%  main2    libantlr4-runtime.so.4.8  [.] antlr4::IntStream::~IntStream
>>
>> Note that these LTO symbols are properly skipped anyway as they belong
>> neither to *text* nor to *data* (is_label && !elf_sec__filter(&shdr,
>> secstrs) is true).
>>
>> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
>> Cc: Peter Zijlstra <peterz@infradead.org>
>> Cc: Ingo Molnar <mingo@redhat.com>
>> Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
>> Cc: Mark Rutland <mark.rutland@arm.com>
>> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
>> Cc: Jiri Olsa <jolsa@redhat.com>
>> Cc: Namhyung Kim <namhyung@kernel.org>
>> ---
>>   tools/perf/util/symbol-elf.c | 10 +++++++++-
>>   1 file changed, 9 insertions(+), 1 deletion(-)
>>
>> diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
>> index f3577f7d72fe..a31b716fa61c 100644
>> --- a/tools/perf/util/symbol-elf.c
>> +++ b/tools/perf/util/symbol-elf.c
>> @@ -1226,12 +1226,20 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
>>   		if (sym.st_shndx == SHN_ABS)
>>   			continue;
>>   
>> -		sec = elf_getscn(runtime_ss->elf, sym.st_shndx);
>> +		sec = elf_getscn(syms_ss->elf, sym.st_shndx);
>>   		if (!sec)
>>   			goto out_elf_end;
> 
> we iterate symbols from syms_ss, so the fix seems to be correct
> to call elf_getscn on syms_ss, not on runtime_ss as we do now
> 
> I'd think this worked only when runtime_ss == syms_ss

No, because the headers are copied 1:1 from runtime_ss to syms_ss. And 
runtime_ss is then stripped, so only .debug* sections are removed there. 
(And syms_ss's are set as NOBITS.)

We iterated .debug* sections in syms_ss and used runtime_ss section 
_headers_ only to adjust symbols (sometimes). That worked.

>>   		gelf_getshdr(sec, &shdr);
>>   
>> +		if (shdr.sh_type == SHT_NOBITS) {
>> +			sec = elf_getscn(runtime_ss->elf, sym.st_shndx);
>> +			if (!sec)
>> +				goto out_elf_end;
>> +
>> +			gelf_getshdr(sec, &shdr);
>> +		}
> 
> is that fallback necessary? the symbol is from syms_ss

Provided the above, we don't need the section data here, only headers, 
so the NOBITS test is superfluous and the fallback shouldn't be needed. 
Let me test it.

thanks,
-- 
js
suse labs

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] perf tools: Resolve symbols against debug file first
  2021-01-13 11:43   ` Jiri Slaby
@ 2021-01-14  4:54     ` Namhyung Kim
  2021-01-14 11:17       ` Michael Ellerman
  0 siblings, 1 reply; 9+ messages in thread
From: Namhyung Kim @ 2021-01-14  4:54 UTC (permalink / raw)
  To: Jiri Slaby
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, linux-kernel,
	Peter Zijlstra, Ingo Molnar, Mark Rutland, Alexander Shishkin,
	linuxppc-dev

Hi both of Jiri,

On Wed, Jan 13, 2021 at 8:43 PM Jiri Slaby <jslaby@suse.cz> wrote:
>
> On 13. 01. 21, 11:46, Jiri Olsa wrote:
> > On Wed, Jan 13, 2021 at 09:01:28AM +0100, Jiri Slaby wrote:
> >> With LTO, there are symbols like these:
> >> /usr/lib/debug/usr/lib64/libantlr4-runtime.so.4.8-4.8-1.4.x86_64.debug
> >>   10305: 0000000000955fa4     0 NOTYPE  LOCAL  DEFAULT   29 Predicate.cpp.2bc410e7
> >>
> >> This comes from a runtime/debug split done by the standard way:
> >> objcopy --only-keep-debug $runtime $debug
> >> objcopy --add-gnu-debuglink=$debugfn -R .comment -R .GCC.command.line --strip-all $runtime
> >>
> >> perf currently cannot resolve such symbols (relicts of LTO), as section
> >> 29 exists only in the debug file (29 is .debug_info). And perf resolves
> >> symbols only against runtime file. This results in all symbols from such
> >> a library being unresolved:
> >>       0.38%  main2    libantlr4-runtime.so.4.8  [.] 0x00000000000671e0
> >>
> >> So try resolving against the debug file first. And only if it fails (the
> >> section has NOBITS set), try runtime file. We can do this, as "objcopy
> >> --only-keep-debug" per documentation preserves all sections, but clears
> >> data of some of them (the runtime ones) and marks them as NOBITS.
> >>
> >> The correct result is now:
> >>       0.38%  main2    libantlr4-runtime.so.4.8  [.] antlr4::IntStream::~IntStream
> >>
> >> Note that these LTO symbols are properly skipped anyway as they belong
> >> neither to *text* nor to *data* (is_label && !elf_sec__filter(&shdr,
> >> secstrs) is true).
> >>
> >> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
> >> Cc: Peter Zijlstra <peterz@infradead.org>
> >> Cc: Ingo Molnar <mingo@redhat.com>
> >> Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
> >> Cc: Mark Rutland <mark.rutland@arm.com>
> >> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
> >> Cc: Jiri Olsa <jolsa@redhat.com>
> >> Cc: Namhyung Kim <namhyung@kernel.org>
> >> ---
> >>   tools/perf/util/symbol-elf.c | 10 +++++++++-
> >>   1 file changed, 9 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
> >> index f3577f7d72fe..a31b716fa61c 100644
> >> --- a/tools/perf/util/symbol-elf.c
> >> +++ b/tools/perf/util/symbol-elf.c
> >> @@ -1226,12 +1226,20 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
> >>              if (sym.st_shndx == SHN_ABS)
> >>                      continue;
> >>
> >> -            sec = elf_getscn(runtime_ss->elf, sym.st_shndx);
> >> +            sec = elf_getscn(syms_ss->elf, sym.st_shndx);
> >>              if (!sec)
> >>                      goto out_elf_end;
> >
> > we iterate symbols from syms_ss, so the fix seems to be correct
> > to call elf_getscn on syms_ss, not on runtime_ss as we do now
> >
> > I'd think this worked only when runtime_ss == syms_ss
>
> No, because the headers are copied 1:1 from runtime_ss to syms_ss. And
> runtime_ss is then stripped, so only .debug* sections are removed there.
> (And syms_ss's are set as NOBITS.)
>
> We iterated .debug* sections in syms_ss and used runtime_ss section
> _headers_ only to adjust symbols (sometimes). That worked.

It seems PPC has an opd section only in the runtime_ss and that's why
we use it for section headers.

>
> >>              gelf_getshdr(sec, &shdr);
> >>
> >> +            if (shdr.sh_type == SHT_NOBITS) {
> >> +                    sec = elf_getscn(runtime_ss->elf, sym.st_shndx);
> >> +                    if (!sec)
> >> +                            goto out_elf_end;
> >> +
> >> +                    gelf_getshdr(sec, &shdr);
> >> +            }
> >
> > is that fallback necessary? the symbol is from syms_ss
>
> Provided the above, we don't need the section data here, only headers,
> so the NOBITS test is superfluous and the fallback shouldn't be needed.
> Let me test it.

We need to talk to PPC folks like I said.  Or maybe we can change the
default ss depending on the arch.

Thanks,
Namhyung

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] perf tools: Resolve symbols against debug file first
  2021-01-14  4:54     ` Namhyung Kim
@ 2021-01-14 11:17       ` Michael Ellerman
  2021-01-15  7:37         ` Namhyung Kim
  0 siblings, 1 reply; 9+ messages in thread
From: Michael Ellerman @ 2021-01-14 11:17 UTC (permalink / raw)
  To: Namhyung Kim, Jiri Slaby
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, linux-kernel,
	Peter Zijlstra, Ingo Molnar, Mark Rutland, Alexander Shishkin,
	linuxppc-dev

Namhyung Kim <namhyung@kernel.org> writes:
> On Wed, Jan 13, 2021 at 8:43 PM Jiri Slaby <jslaby@suse.cz> wrote:
>>
>> On 13. 01. 21, 11:46, Jiri Olsa wrote:
>> > On Wed, Jan 13, 2021 at 09:01:28AM +0100, Jiri Slaby wrote:
>> >> With LTO, there are symbols like these:
>> >> /usr/lib/debug/usr/lib64/libantlr4-runtime.so.4.8-4.8-1.4.x86_64.debug
>> >>   10305: 0000000000955fa4     0 NOTYPE  LOCAL  DEFAULT   29 Predicate.cpp.2bc410e7
>> >>
>> >> This comes from a runtime/debug split done by the standard way:
>> >> objcopy --only-keep-debug $runtime $debug
>> >> objcopy --add-gnu-debuglink=$debugfn -R .comment -R .GCC.command.line --strip-all $runtime
>> >>
...
>> >> diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
>> >> index f3577f7d72fe..a31b716fa61c 100644
>> >> --- a/tools/perf/util/symbol-elf.c
>> >> +++ b/tools/perf/util/symbol-elf.c
>> >> @@ -1226,12 +1226,20 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
>> >>              if (sym.st_shndx == SHN_ABS)
>> >>                      continue;
>> >>
>> >> -            sec = elf_getscn(runtime_ss->elf, sym.st_shndx);
>> >> +            sec = elf_getscn(syms_ss->elf, sym.st_shndx);
>> >>              if (!sec)
>> >>                      goto out_elf_end;
>> >
>> > we iterate symbols from syms_ss, so the fix seems to be correct
>> > to call elf_getscn on syms_ss, not on runtime_ss as we do now
>> >
>> > I'd think this worked only when runtime_ss == syms_ss
>>
>> No, because the headers are copied 1:1 from runtime_ss to syms_ss. And
>> runtime_ss is then stripped, so only .debug* sections are removed there.
>> (And syms_ss's are set as NOBITS.)
>>
>> We iterated .debug* sections in syms_ss and used runtime_ss section
>> _headers_ only to adjust symbols (sometimes). That worked.
>
> It seems PPC has an opd section only in the runtime_ss and that's why
> we use it for section headers.

At least on my system (Ubuntu 20.04.1) I see .opd in the debug file with
NOBITS set:

$ readelf -e vmlinux.debug | grep opd
  [37] .opd              NOBITS           c000000001c1f548  01202e14


But possibly that's not the case with older toolchains?

cheers

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] perf tools: Resolve symbols against debug file first
  2021-01-14 11:17       ` Michael Ellerman
@ 2021-01-15  7:37         ` Namhyung Kim
  0 siblings, 0 replies; 9+ messages in thread
From: Namhyung Kim @ 2021-01-15  7:37 UTC (permalink / raw)
  To: Michael Ellerman
  Cc: Jiri Slaby, Jiri Olsa, Arnaldo Carvalho de Melo, linux-kernel,
	Peter Zijlstra, Ingo Molnar, Mark Rutland, Alexander Shishkin,
	linuxppc-dev

Hello,

On Thu, Jan 14, 2021 at 8:17 PM Michael Ellerman <mpe@ellerman.id.au> wrote:
>
> Namhyung Kim <namhyung@kernel.org> writes:
> > On Wed, Jan 13, 2021 at 8:43 PM Jiri Slaby <jslaby@suse.cz> wrote:
> >>
> >> On 13. 01. 21, 11:46, Jiri Olsa wrote:
> >> > On Wed, Jan 13, 2021 at 09:01:28AM +0100, Jiri Slaby wrote:
> >> >> With LTO, there are symbols like these:
> >> >> /usr/lib/debug/usr/lib64/libantlr4-runtime.so.4.8-4.8-1.4.x86_64.debug
> >> >>   10305: 0000000000955fa4     0 NOTYPE  LOCAL  DEFAULT   29 Predicate.cpp.2bc410e7
> >> >>
> >> >> This comes from a runtime/debug split done by the standard way:
> >> >> objcopy --only-keep-debug $runtime $debug
> >> >> objcopy --add-gnu-debuglink=$debugfn -R .comment -R .GCC.command.line --strip-all $runtime
> >> >>
> ...
> >> >> diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
> >> >> index f3577f7d72fe..a31b716fa61c 100644
> >> >> --- a/tools/perf/util/symbol-elf.c
> >> >> +++ b/tools/perf/util/symbol-elf.c
> >> >> @@ -1226,12 +1226,20 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
> >> >>              if (sym.st_shndx == SHN_ABS)
> >> >>                      continue;
> >> >>
> >> >> -            sec = elf_getscn(runtime_ss->elf, sym.st_shndx);
> >> >> +            sec = elf_getscn(syms_ss->elf, sym.st_shndx);
> >> >>              if (!sec)
> >> >>                      goto out_elf_end;
> >> >
> >> > we iterate symbols from syms_ss, so the fix seems to be correct
> >> > to call elf_getscn on syms_ss, not on runtime_ss as we do now
> >> >
> >> > I'd think this worked only when runtime_ss == syms_ss
> >>
> >> No, because the headers are copied 1:1 from runtime_ss to syms_ss. And
> >> runtime_ss is then stripped, so only .debug* sections are removed there.
> >> (And syms_ss's are set as NOBITS.)
> >>
> >> We iterated .debug* sections in syms_ss and used runtime_ss section
> >> _headers_ only to adjust symbols (sometimes). That worked.
> >
> > It seems PPC has an opd section only in the runtime_ss and that's why
> > we use it for section headers.
>
> At least on my system (Ubuntu 20.04.1) I see .opd in the debug file with
> NOBITS set:
>
> $ readelf -e vmlinux.debug | grep opd
>   [37] .opd              NOBITS           c000000001c1f548  01202e14
>
>
> But possibly that's not the case with older toolchains?

I was referring to this commit:

commit 261360b6e90a782f0a63d8f61a67683c376c88cf
Author: Cody P Schafer <cody@linux.vnet.ibm.com>
Date:   Fri Aug 10 15:23:01 2012 -0700

    perf symbols: Convert dso__load_syms to take 2 symsrc's

    To properly handle platforms with an opd section, both a runtime image
    (which contains the opd section but possibly lacks symbols) and a symbol
    image (which probably lacks an opd section but has symbols).

    The next patch ("perf symbol: use both runtime and debug images")
    adjusts the callsite in dso__load() to take advantage of being able to
    pass both runtime & debug images.

    Assumptions made here:

     - The opd section, if it exists in the runtime image, has headers in
       both the runtime image and the debug/syms image.

     - The index of the opd section (again, only if it exists in the runtime
       image) is the same in both the runtime and debug/symbols image.

    Both of these are true on RHEL, but it is unclear how accurate they are
    in general (on platforms with function descriptors in opd sections).

    Signed-off-by: Cody P Schafer <cody@linux.vnet.ibm.com>


Thanks,
Namhyung

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] perf tools: Resolve symbols against debug file first
  2021-01-13 10:46 ` Jiri Olsa
  2021-01-13 11:43   ` Jiri Slaby
@ 2021-01-28 10:43   ` Jiri Slaby
  2021-02-03  4:28     ` Namhyung Kim
  2021-02-03 19:32     ` Jiri Olsa
  1 sibling, 2 replies; 9+ messages in thread
From: Jiri Slaby @ 2021-01-28 10:43 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: acme, linux-kernel, Peter Zijlstra, Ingo Molnar, Mark Rutland,
	Alexander Shishkin, Namhyung Kim

On 13. 01. 21, 11:46, Jiri Olsa wrote:
> On Wed, Jan 13, 2021 at 09:01:28AM +0100, Jiri Slaby wrote:
>> With LTO, there are symbols like these:
>> /usr/lib/debug/usr/lib64/libantlr4-runtime.so.4.8-4.8-1.4.x86_64.debug
>>   10305: 0000000000955fa4     0 NOTYPE  LOCAL  DEFAULT   29 Predicate.cpp.2bc410e7
>>
>> This comes from a runtime/debug split done by the standard way:
>> objcopy --only-keep-debug $runtime $debug
>> objcopy --add-gnu-debuglink=$debugfn -R .comment -R .GCC.command.line --strip-all $runtime
>>
>> perf currently cannot resolve such symbols (relicts of LTO), as section
>> 29 exists only in the debug file (29 is .debug_info). And perf resolves
>> symbols only against runtime file. This results in all symbols from such
>> a library being unresolved:
>>       0.38%  main2    libantlr4-runtime.so.4.8  [.] 0x00000000000671e0
>>
>> So try resolving against the debug file first. And only if it fails (the
>> section has NOBITS set), try runtime file. We can do this, as "objcopy
>> --only-keep-debug" per documentation preserves all sections, but clears
>> data of some of them (the runtime ones) and marks them as NOBITS.
>>
>> The correct result is now:
>>       0.38%  main2    libantlr4-runtime.so.4.8  [.] antlr4::IntStream::~IntStream
>>
>> Note that these LTO symbols are properly skipped anyway as they belong
>> neither to *text* nor to *data* (is_label && !elf_sec__filter(&shdr,
>> secstrs) is true).
>>
>> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
>> Cc: Peter Zijlstra <peterz@infradead.org>
>> Cc: Ingo Molnar <mingo@redhat.com>
>> Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
>> Cc: Mark Rutland <mark.rutland@arm.com>
>> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
>> Cc: Jiri Olsa <jolsa@redhat.com>
>> Cc: Namhyung Kim <namhyung@kernel.org>
>> ---
>>   tools/perf/util/symbol-elf.c | 10 +++++++++-
>>   1 file changed, 9 insertions(+), 1 deletion(-)
>>
>> diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
>> index f3577f7d72fe..a31b716fa61c 100644
>> --- a/tools/perf/util/symbol-elf.c
>> +++ b/tools/perf/util/symbol-elf.c
>> @@ -1226,12 +1226,20 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
>>   		if (sym.st_shndx == SHN_ABS)
>>   			continue;
>>   
>> -		sec = elf_getscn(runtime_ss->elf, sym.st_shndx);
>> +		sec = elf_getscn(syms_ss->elf, sym.st_shndx);
>>   		if (!sec)
>>   			goto out_elf_end;
> 
> we iterate symbols from syms_ss, so the fix seems to be correct
> to call elf_getscn on syms_ss, not on runtime_ss as we do now
> 
> I'd think this worked only when runtime_ss == syms_ss
> 
>>   
>>   		gelf_getshdr(sec, &shdr);
>>   
>> +		if (shdr.sh_type == SHT_NOBITS) {
>> +			sec = elf_getscn(runtime_ss->elf, sym.st_shndx);
>> +			if (!sec)
>> +				goto out_elf_end;
>> +
>> +			gelf_getshdr(sec, &shdr);
>> +		}
> 
> is that fallback necessary? the symbol is from syms_ss

To resume this and answer:

Yes, the fallback is necessary.

It's because syms_ss section header has NOBITS set for the sections, so 
file offset is not incremented. So shdr.sh_offset (the file offset) used 
further in dso__load_sym has different values for syms and runtime. The 
syms_ss (the NOBITS) one is invalid as it has 0x1000 here. The runtime 
one contains good values (like 000509d0 here):

.text         00082560  00000000000509d0  00000000000509d0  [-00001000-] 
  {+000509d0+}  2**4

That is, without the fallback, the computed symbol address is wrong.

thanks,
-- 
js
suse labs

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] perf tools: Resolve symbols against debug file first
  2021-01-28 10:43   ` Jiri Slaby
@ 2021-02-03  4:28     ` Namhyung Kim
  2021-02-03 19:32     ` Jiri Olsa
  1 sibling, 0 replies; 9+ messages in thread
From: Namhyung Kim @ 2021-02-03  4:28 UTC (permalink / raw)
  To: Jiri Slaby
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, linux-kernel,
	Peter Zijlstra, Ingo Molnar, Mark Rutland, Alexander Shishkin

Hello,

On Thu, Jan 28, 2021 at 7:43 PM Jiri Slaby <jslaby@suse.cz> wrote:
>
> On 13. 01. 21, 11:46, Jiri Olsa wrote:
> > On Wed, Jan 13, 2021 at 09:01:28AM +0100, Jiri Slaby wrote:
> >> With LTO, there are symbols like these:
> >> /usr/lib/debug/usr/lib64/libantlr4-runtime.so.4.8-4.8-1.4.x86_64.debug
> >>   10305: 0000000000955fa4     0 NOTYPE  LOCAL  DEFAULT   29 Predicate.cpp.2bc410e7
> >>
> >> This comes from a runtime/debug split done by the standard way:
> >> objcopy --only-keep-debug $runtime $debug
> >> objcopy --add-gnu-debuglink=$debugfn -R .comment -R .GCC.command.line --strip-all $runtime
> >>
> >> perf currently cannot resolve such symbols (relicts of LTO), as section
> >> 29 exists only in the debug file (29 is .debug_info). And perf resolves
> >> symbols only against runtime file. This results in all symbols from such
> >> a library being unresolved:
> >>       0.38%  main2    libantlr4-runtime.so.4.8  [.] 0x00000000000671e0
> >>
> >> So try resolving against the debug file first. And only if it fails (the
> >> section has NOBITS set), try runtime file. We can do this, as "objcopy
> >> --only-keep-debug" per documentation preserves all sections, but clears
> >> data of some of them (the runtime ones) and marks them as NOBITS.
> >>
> >> The correct result is now:
> >>       0.38%  main2    libantlr4-runtime.so.4.8  [.] antlr4::IntStream::~IntStream
> >>
> >> Note that these LTO symbols are properly skipped anyway as they belong
> >> neither to *text* nor to *data* (is_label && !elf_sec__filter(&shdr,
> >> secstrs) is true).
> >>
> >> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
> >> Cc: Peter Zijlstra <peterz@infradead.org>
> >> Cc: Ingo Molnar <mingo@redhat.com>
> >> Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
> >> Cc: Mark Rutland <mark.rutland@arm.com>
> >> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
> >> Cc: Jiri Olsa <jolsa@redhat.com>
> >> Cc: Namhyung Kim <namhyung@kernel.org>
> >> ---
> >>   tools/perf/util/symbol-elf.c | 10 +++++++++-
> >>   1 file changed, 9 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
> >> index f3577f7d72fe..a31b716fa61c 100644
> >> --- a/tools/perf/util/symbol-elf.c
> >> +++ b/tools/perf/util/symbol-elf.c
> >> @@ -1226,12 +1226,20 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
> >>              if (sym.st_shndx == SHN_ABS)
> >>                      continue;
> >>
> >> -            sec = elf_getscn(runtime_ss->elf, sym.st_shndx);
> >> +            sec = elf_getscn(syms_ss->elf, sym.st_shndx);
> >>              if (!sec)
> >>                      goto out_elf_end;
> >
> > we iterate symbols from syms_ss, so the fix seems to be correct
> > to call elf_getscn on syms_ss, not on runtime_ss as we do now
> >
> > I'd think this worked only when runtime_ss == syms_ss
> >
> >>
> >>              gelf_getshdr(sec, &shdr);
> >>
> >> +            if (shdr.sh_type == SHT_NOBITS) {
> >> +                    sec = elf_getscn(runtime_ss->elf, sym.st_shndx);
> >> +                    if (!sec)
> >> +                            goto out_elf_end;
> >> +
> >> +                    gelf_getshdr(sec, &shdr);
> >> +            }
> >
> > is that fallback necessary? the symbol is from syms_ss
>
> To resume this and answer:
>
> Yes, the fallback is necessary.
>
> It's because syms_ss section header has NOBITS set for the sections, so
> file offset is not incremented. So shdr.sh_offset (the file offset) used
> further in dso__load_sym has different values for syms and runtime. The
> syms_ss (the NOBITS) one is invalid as it has 0x1000 here. The runtime
> one contains good values (like 000509d0 here):
>
> .text         00082560  00000000000509d0  00000000000509d0  [-00001000-]
>   {+000509d0+}  2**4
>
> That is, without the fallback, the computed symbol address is wrong.

Acked-by: Namhyung Kim <namhyung@kernel.org>

Thanks,
Namhyung

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] perf tools: Resolve symbols against debug file first
  2021-01-28 10:43   ` Jiri Slaby
  2021-02-03  4:28     ` Namhyung Kim
@ 2021-02-03 19:32     ` Jiri Olsa
  1 sibling, 0 replies; 9+ messages in thread
From: Jiri Olsa @ 2021-02-03 19:32 UTC (permalink / raw)
  To: Jiri Slaby
  Cc: acme, linux-kernel, Peter Zijlstra, Ingo Molnar, Mark Rutland,
	Alexander Shishkin, Namhyung Kim

On Thu, Jan 28, 2021 at 11:43:07AM +0100, Jiri Slaby wrote:
> On 13. 01. 21, 11:46, Jiri Olsa wrote:
> > On Wed, Jan 13, 2021 at 09:01:28AM +0100, Jiri Slaby wrote:
> > > With LTO, there are symbols like these:
> > > /usr/lib/debug/usr/lib64/libantlr4-runtime.so.4.8-4.8-1.4.x86_64.debug
> > >   10305: 0000000000955fa4     0 NOTYPE  LOCAL  DEFAULT   29 Predicate.cpp.2bc410e7
> > > 
> > > This comes from a runtime/debug split done by the standard way:
> > > objcopy --only-keep-debug $runtime $debug
> > > objcopy --add-gnu-debuglink=$debugfn -R .comment -R .GCC.command.line --strip-all $runtime
> > > 
> > > perf currently cannot resolve such symbols (relicts of LTO), as section
> > > 29 exists only in the debug file (29 is .debug_info). And perf resolves
> > > symbols only against runtime file. This results in all symbols from such
> > > a library being unresolved:
> > >       0.38%  main2    libantlr4-runtime.so.4.8  [.] 0x00000000000671e0
> > > 
> > > So try resolving against the debug file first. And only if it fails (the
> > > section has NOBITS set), try runtime file. We can do this, as "objcopy
> > > --only-keep-debug" per documentation preserves all sections, but clears
> > > data of some of them (the runtime ones) and marks them as NOBITS.
> > > 
> > > The correct result is now:
> > >       0.38%  main2    libantlr4-runtime.so.4.8  [.] antlr4::IntStream::~IntStream
> > > 
> > > Note that these LTO symbols are properly skipped anyway as they belong
> > > neither to *text* nor to *data* (is_label && !elf_sec__filter(&shdr,
> > > secstrs) is true).
> > > 
> > > Signed-off-by: Jiri Slaby <jslaby@suse.cz>
> > > Cc: Peter Zijlstra <peterz@infradead.org>
> > > Cc: Ingo Molnar <mingo@redhat.com>
> > > Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
> > > Cc: Mark Rutland <mark.rutland@arm.com>
> > > Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
> > > Cc: Jiri Olsa <jolsa@redhat.com>
> > > Cc: Namhyung Kim <namhyung@kernel.org>
> > > ---
> > >   tools/perf/util/symbol-elf.c | 10 +++++++++-
> > >   1 file changed, 9 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
> > > index f3577f7d72fe..a31b716fa61c 100644
> > > --- a/tools/perf/util/symbol-elf.c
> > > +++ b/tools/perf/util/symbol-elf.c
> > > @@ -1226,12 +1226,20 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
> > >   		if (sym.st_shndx == SHN_ABS)
> > >   			continue;
> > > -		sec = elf_getscn(runtime_ss->elf, sym.st_shndx);
> > > +		sec = elf_getscn(syms_ss->elf, sym.st_shndx);
> > >   		if (!sec)
> > >   			goto out_elf_end;
> > 
> > we iterate symbols from syms_ss, so the fix seems to be correct
> > to call elf_getscn on syms_ss, not on runtime_ss as we do now
> > 
> > I'd think this worked only when runtime_ss == syms_ss
> > 
> > >   		gelf_getshdr(sec, &shdr);
> > > +		if (shdr.sh_type == SHT_NOBITS) {
> > > +			sec = elf_getscn(runtime_ss->elf, sym.st_shndx);
> > > +			if (!sec)
> > > +				goto out_elf_end;
> > > +
> > > +			gelf_getshdr(sec, &shdr);
> > > +		}
> > 
> > is that fallback necessary? the symbol is from syms_ss
> 
> To resume this and answer:
> 
> Yes, the fallback is necessary.
> 
> It's because syms_ss section header has NOBITS set for the sections, so file
> offset is not incremented. So shdr.sh_offset (the file offset) used further
> in dso__load_sym has different values for syms and runtime. The syms_ss (the
> NOBITS) one is invalid as it has 0x1000 here. The runtime one contains good
> values (like 000509d0 here):
> 
> .text         00082560  00000000000509d0  00000000000509d0  [-00001000-]
> {+000509d0+}  2**4
> 
> That is, without the fallback, the computed symbol address is wrong.

thanks for explanation, could you please put this comment in the code?

thanks,
jirka


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2021-02-03 19:33 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-13  8:01 [PATCH] perf tools: Resolve symbols against debug file first Jiri Slaby
2021-01-13 10:46 ` Jiri Olsa
2021-01-13 11:43   ` Jiri Slaby
2021-01-14  4:54     ` Namhyung Kim
2021-01-14 11:17       ` Michael Ellerman
2021-01-15  7:37         ` Namhyung Kim
2021-01-28 10:43   ` Jiri Slaby
2021-02-03  4:28     ` Namhyung Kim
2021-02-03 19:32     ` Jiri Olsa

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).