linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* perf does not resolve plt symbols from libstdc++ right (.plt.sec problem)
@ 2021-01-11  6:31 Jiri Slaby
  2021-03-29  9:09 ` Jiri Slaby
  0 siblings, 1 reply; 7+ messages in thread
From: Jiri Slaby @ 2021-01-11  6:31 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim,
	linux-kernel, Richard Guenther, H.J. Lu

Hi,

this e-mails is a follow-up of my report at:
https://bugzilla.suse.com/show_bug.cgi?id=1180681

There is a problem with *@plt symbols in some libraries, they are 
unresolved by perf (memcmp@plt in this case):
 >     0.26%  main2    /usr/lib64/libstdc++.so.6.0.28            0xa51a0 
            l [.] 0x00000000000a51a0

On the other hand, plt symbols in other libraries are fine (memset@plt 
in this case):
 >     0.17%  main2    /usr/lib64/libantlr4-runtime.so.4.8       0x4ed10 
            l [.] memset@plt

I dumped memcmp's .plt.rela entries in perf:
/usr/lib64/libantlr4-runtime.so.4.8: 154th addr=4e9d0 plt_off=4e020 
hdr=10 entry=10
/usr/lib64/libstdc++.so.6.0.28: 772th addr=a1070 plt_off=9e020 hdr=10 
entry=10

The difference (offset) of stdc++'s memcmp is 0xa51a0 (correct) - 
0xa1070 (perf's computed) = 0x4130.

The problem is perf assumes nth entry of .plt.rela to correspond to nth 
function in .plt, but memcmp is in .plt.sec in libstdc++.so:

 > Relocation section '.rela.plt' at offset 0x97900 contains 1018 entries:
 >     Offset             Info             Type               Symbol's 
Value  Symbol's Name + Addend
 > ...
 > 00000000001dc838  0000007800000007 R_X86_64_JUMP_SLOT 
0000000000000000 memcmp@GLIBC_2.2.5 + 0

Perf does this with the rela entries:
https://github.com/torvalds/linux/blob/f5e6c330254ae691f6d7befe61c786eb5056007e/tools/perf/util/symbol-elf.c#L385

It takes a symbol index from sym.r_info. Then it resolves its name from 
.dynsym, appending "@plt" to it. Then this name is added to perf's 
symbol table along with address which is computed as .rela.plt index 
multiplied by entry size (shdr_plt.sh_entsize) plus plt header 
(shdr_plt.sh_entsize on x86_64 too).

And from this comes (almost) the offset above:
 > $ objdump -h /usr/lib64/libstdc++.so.6|grep -E ' .plt(\.sec)? '
 >  12 .plt          00003fb0  000000000009e020  000000000009e020 
0009e020  2**4
 >  14 .plt.sec      00003fa0  00000000000a2160  00000000000a2160 
000a2160  2**4

0xa2160-0x9e020 = 0x4140. I assume the 0x10 difference is that perf adds 
shdr_plt.sh_entsize (0x10) to the offset to skip the first .plt entry 
(header).

Richard writes:
======
.plt.sec is IIRC the "second" (sec) PLT entry - the one that will be 
used on the second call (and on).  This is used / emitted for ELF object 
instrumented for Intel CET.  The details escape me for the moment but I 
hope the x86 ABI documents this (and the constraints) in detail.
======

How should perf find out whether to consider .plt or .plt.sec? Or 
generally, how to properly find an address of *@plt symbols like 
memcmp@plt above?

thanks,
-- 
js
suse labs

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

* Re: perf does not resolve plt symbols from libstdc++ right (.plt.sec problem)
  2021-01-11  6:31 perf does not resolve plt symbols from libstdc++ right (.plt.sec problem) Jiri Slaby
@ 2021-03-29  9:09 ` Jiri Slaby
  2021-03-29  9:38   ` Richard Biener
  0 siblings, 1 reply; 7+ messages in thread
From: Jiri Slaby @ 2021-03-29  9:09 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim,
	linux-kernel, Richard Guenther, H.J. Lu

Any ideas on this?

On 11. 01. 21, 7:31, Jiri Slaby wrote:
> Hi,
> 
> this e-mails is a follow-up of my report at:
> https://bugzilla.suse.com/show_bug.cgi?id=1180681
> 
> There is a problem with *@plt symbols in some libraries, they are 
> unresolved by perf (memcmp@plt in this case):
>  >     0.26%  main2    /usr/lib64/libstdc++.so.6.0.28            0xa51a0 
>             l [.] 0x00000000000a51a0
> 
> On the other hand, plt symbols in other libraries are fine (memset@plt 
> in this case):
>  >     0.17%  main2    /usr/lib64/libantlr4-runtime.so.4.8       0x4ed10 
>             l [.] memset@plt
> 
> I dumped memcmp's .plt.rela entries in perf:
> /usr/lib64/libantlr4-runtime.so.4.8: 154th addr=4e9d0 plt_off=4e020 
> hdr=10 entry=10
> /usr/lib64/libstdc++.so.6.0.28: 772th addr=a1070 plt_off=9e020 hdr=10 
> entry=10
> 
> The difference (offset) of stdc++'s memcmp is 0xa51a0 (correct) - 
> 0xa1070 (perf's computed) = 0x4130.
> 
> The problem is perf assumes nth entry of .plt.rela to correspond to nth 
> function in .plt, but memcmp is in .plt.sec in libstdc++.so:
> 
>  > Relocation section '.rela.plt' at offset 0x97900 contains 1018 entries:
>  >     Offset             Info             Type               Symbol's 
> Value  Symbol's Name + Addend
>  > ...
>  > 00000000001dc838  0000007800000007 R_X86_64_JUMP_SLOT 
> 0000000000000000 memcmp@GLIBC_2.2.5 + 0
> 
> Perf does this with the rela entries:
> https://github.com/torvalds/linux/blob/f5e6c330254ae691f6d7befe61c786eb5056007e/tools/perf/util/symbol-elf.c#L385 
> 
> 
> It takes a symbol index from sym.r_info. Then it resolves its name from 
> .dynsym, appending "@plt" to it. Then this name is added to perf's 
> symbol table along with address which is computed as .rela.plt index 
> multiplied by entry size (shdr_plt.sh_entsize) plus plt header 
> (shdr_plt.sh_entsize on x86_64 too).
> 
> And from this comes (almost) the offset above:
>  > $ objdump -h /usr/lib64/libstdc++.so.6|grep -E ' .plt(\.sec)? '
>  >  12 .plt          00003fb0  000000000009e020  000000000009e020 
> 0009e020  2**4
>  >  14 .plt.sec      00003fa0  00000000000a2160  00000000000a2160 
> 000a2160  2**4
> 
> 0xa2160-0x9e020 = 0x4140. I assume the 0x10 difference is that perf adds 
> shdr_plt.sh_entsize (0x10) to the offset to skip the first .plt entry 
> (header).
> 
> Richard writes:
> ======
> .plt.sec is IIRC the "second" (sec) PLT entry - the one that will be 
> used on the second call (and on).  This is used / emitted for ELF object 
> instrumented for Intel CET.  The details escape me for the moment but I 
> hope the x86 ABI documents this (and the constraints) in detail.
> ======
> 
> How should perf find out whether to consider .plt or .plt.sec? Or 
> generally, how to properly find an address of *@plt symbols like 
> memcmp@plt above?
> 
> thanks,


-- 
js
suse labs

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

* Re: perf does not resolve plt symbols from libstdc++ right (.plt.sec problem)
  2021-03-29  9:09 ` Jiri Slaby
@ 2021-03-29  9:38   ` Richard Biener
  2021-03-29 12:52     ` H.J. Lu
  0 siblings, 1 reply; 7+ messages in thread
From: Richard Biener @ 2021-03-29  9:38 UTC (permalink / raw)
  To: Jiri Slaby
  Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim,
	linux-kernel, H.J. Lu

[-- Attachment #1: Type: text/plain, Size: 3222 bytes --]

On Mon, 29 Mar 2021, Jiri Slaby wrote:

> Any ideas on this?
> 
> On 11. 01. 21, 7:31, Jiri Slaby wrote:
> > Hi,
> > 
> > this e-mails is a follow-up of my report at:
> > https://bugzilla.suse.com/show_bug.cgi?id=1180681
> > 
> > There is a problem with *@plt symbols in some libraries, they are unresolved
> > by perf (memcmp@plt in this case):
> >  >     0.26%  main2    /usr/lib64/libstdc++.so.6.0.28            0xa51a0 
> >             l [.] 0x00000000000a51a0
> > 
> > On the other hand, plt symbols in other libraries are fine (memset@plt in
> > this case):
> >  >     0.17%  main2    /usr/lib64/libantlr4-runtime.so.4.8       0x4ed10 
> >             l [.] memset@plt
> > 
> > I dumped memcmp's .plt.rela entries in perf:
> > /usr/lib64/libantlr4-runtime.so.4.8: 154th addr=4e9d0 plt_off=4e020 hdr=10
> > entry=10
> > /usr/lib64/libstdc++.so.6.0.28: 772th addr=a1070 plt_off=9e020 hdr=10
> > entry=10
> > 
> > The difference (offset) of stdc++'s memcmp is 0xa51a0 (correct) - 0xa1070
> > (perf's computed) = 0x4130.
> > 
> > The problem is perf assumes nth entry of .plt.rela to correspond to nth
> > function in .plt, but memcmp is in .plt.sec in libstdc++.so:
> > 
> >  >Relocation section '.rela.plt' at offset 0x97900 contains 1018 entries:
> >  >     Offset             Info             Type               Symbol's 
> > Value  Symbol's Name + Addend
> >  > ...
> >  > 00000000001dc838  0000007800000007 R_X86_64_JUMP_SLOT 
> > 0000000000000000 memcmp@GLIBC_2.2.5 + 0
> > 
> > Perf does this with the rela entries:
> > https://github.com/torvalds/linux/blob/f5e6c330254ae691f6d7befe61c786eb5056007e/tools/perf/util/symbol-elf.c#L385 
> > 
> > It takes a symbol index from sym.r_info. Then it resolves its name from
> > .dynsym, appending "@plt" to it. Then this name is added to perf's symbol
> > table along with address which is computed as .rela.plt index multiplied by
> > entry size (shdr_plt.sh_entsize) plus plt header (shdr_plt.sh_entsize on
> > x86_64 too).
> > 
> > And from this comes (almost) the offset above:
> >  >$ objdump -h /usr/lib64/libstdc++.so.6|grep -E ' .plt(\.sec)? '
> >  >  12 .plt          00003fb0  000000000009e020  000000000009e020 
> > 0009e020  2**4
> >  >  14 .plt.sec      00003fa0  00000000000a2160  00000000000a2160 
> > 000a2160  2**4
> > 
> > 0xa2160-0x9e020 = 0x4140. I assume the 0x10 difference is that perf adds
> > shdr_plt.sh_entsize (0x10) to the offset to skip the first .plt entry
> > (header).
> > 
> > Richard writes:
> > ======
> > .plt.sec is IIRC the "second" (sec) PLT entry - the one that will be used on
> > the second call (and on).  This is used / emitted for ELF object
> > instrumented for Intel CET.  The details escape me for the moment but I hope
> > the x86 ABI documents this (and the constraints) in detail.

I just checked and the x86_64 psABI doesn't say anything about .plt.sec

> > ======
> > 
> > How should perf find out whether to consider .plt or .plt.sec? Or generally,
> > how to properly find an address of *@plt symbols like memcmp@plt above?
> > thanks,
> 
> 
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)

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

* Re: perf does not resolve plt symbols from libstdc++ right (.plt.sec problem)
  2021-03-29  9:38   ` Richard Biener
@ 2021-03-29 12:52     ` H.J. Lu
  2021-03-29 13:06       ` Richard Biener
  0 siblings, 1 reply; 7+ messages in thread
From: H.J. Lu @ 2021-03-29 12:52 UTC (permalink / raw)
  To: Richard Biener
  Cc: Jiri Slaby, Peter Zijlstra, Ingo Molnar,
	Arnaldo Carvalho de Melo, Mark Rutland, Alexander Shishkin,
	Jiri Olsa, Namhyung Kim, LKML

On Mon, Mar 29, 2021 at 2:38 AM Richard Biener <rguenther@suse.de> wrote:
>
> On Mon, 29 Mar 2021, Jiri Slaby wrote:
>
> > Any ideas on this?
> >
> > On 11. 01. 21, 7:31, Jiri Slaby wrote:
> > > Hi,
> > >
> > > this e-mails is a follow-up of my report at:
> > > https://bugzilla.suse.com/show_bug.cgi?id=1180681
> > >
> > > There is a problem with *@plt symbols in some libraries, they are unresolved
> > > by perf (memcmp@plt in this case):
> > >  >     0.26%  main2    /usr/lib64/libstdc++.so.6.0.28            0xa51a0
> > >             l [.] 0x00000000000a51a0
> > >
> > > On the other hand, plt symbols in other libraries are fine (memset@plt in
> > > this case):
> > >  >     0.17%  main2    /usr/lib64/libantlr4-runtime.so.4.8       0x4ed10
> > >             l [.] memset@plt
> > >
> > > I dumped memcmp's .plt.rela entries in perf:
> > > /usr/lib64/libantlr4-runtime.so.4.8: 154th addr=4e9d0 plt_off=4e020 hdr=10
> > > entry=10
> > > /usr/lib64/libstdc++.so.6.0.28: 772th addr=a1070 plt_off=9e020 hdr=10
> > > entry=10
> > >
> > > The difference (offset) of stdc++'s memcmp is 0xa51a0 (correct) - 0xa1070
> > > (perf's computed) = 0x4130.
> > >
> > > The problem is perf assumes nth entry of .plt.rela to correspond to nth
> > > function in .plt, but memcmp is in .plt.sec in libstdc++.so:
> > >
> > >  >Relocation section '.rela.plt' at offset 0x97900 contains 1018 entries:
> > >  >     Offset             Info             Type               Symbol's
> > > Value  Symbol's Name + Addend
> > >  > ...
> > >  > 00000000001dc838  0000007800000007 R_X86_64_JUMP_SLOT
> > > 0000000000000000 memcmp@GLIBC_2.2.5 + 0
> > >
> > > Perf does this with the rela entries:
> > > https://github.com/torvalds/linux/blob/f5e6c330254ae691f6d7befe61c786eb5056007e/tools/perf/util/symbol-elf.c#L385
> > >
> > > It takes a symbol index from sym.r_info. Then it resolves its name from
> > > .dynsym, appending "@plt" to it. Then this name is added to perf's symbol
> > > table along with address which is computed as .rela.plt index multiplied by
> > > entry size (shdr_plt.sh_entsize) plus plt header (shdr_plt.sh_entsize on
> > > x86_64 too).
> > >
> > > And from this comes (almost) the offset above:
> > >  >$ objdump -h /usr/lib64/libstdc++.so.6|grep -E ' .plt(\.sec)? '
> > >  >  12 .plt          00003fb0  000000000009e020  000000000009e020
> > > 0009e020  2**4
> > >  >  14 .plt.sec      00003fa0  00000000000a2160  00000000000a2160
> > > 000a2160  2**4
> > >
> > > 0xa2160-0x9e020 = 0x4140. I assume the 0x10 difference is that perf adds
> > > shdr_plt.sh_entsize (0x10) to the offset to skip the first .plt entry
> > > (header).
> > >
> > > Richard writes:
> > > ======
> > > .plt.sec is IIRC the "second" (sec) PLT entry - the one that will be used on
> > > the second call (and on).  This is used / emitted for ELF object
> > > instrumented for Intel CET.  The details escape me for the moment but I hope
> > > the x86 ABI documents this (and the constraints) in detail.
>
> I just checked and the x86_64 psABI doesn't say anything about .plt.sec

The second PLT is documented in section 13.2 Dynamic Linking in x86-64
psABI.  Please see elf_x86_64_get_synthetic_symtab in binutils for PLT symbol
processing.

-- 
H.J.

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

* Re: perf does not resolve plt symbols from libstdc++ right (.plt.sec problem)
  2021-03-29 12:52     ` H.J. Lu
@ 2021-03-29 13:06       ` Richard Biener
  2021-03-29 13:10         ` H.J. Lu
  0 siblings, 1 reply; 7+ messages in thread
From: Richard Biener @ 2021-03-29 13:06 UTC (permalink / raw)
  To: H.J. Lu
  Cc: Jiri Slaby, Peter Zijlstra, Ingo Molnar,
	Arnaldo Carvalho de Melo, Mark Rutland, Alexander Shishkin,
	Jiri Olsa, Namhyung Kim, LKML

[-- Attachment #1: Type: text/plain, Size: 3865 bytes --]

On Mon, 29 Mar 2021, H.J. Lu wrote:

> On Mon, Mar 29, 2021 at 2:38 AM Richard Biener <rguenther@suse.de> wrote:
> >
> > On Mon, 29 Mar 2021, Jiri Slaby wrote:
> >
> > > Any ideas on this?
> > >
> > > On 11. 01. 21, 7:31, Jiri Slaby wrote:
> > > > Hi,
> > > >
> > > > this e-mails is a follow-up of my report at:
> > > > https://bugzilla.suse.com/show_bug.cgi?id=1180681
> > > >
> > > > There is a problem with *@plt symbols in some libraries, they are unresolved
> > > > by perf (memcmp@plt in this case):
> > > >  >     0.26%  main2    /usr/lib64/libstdc++.so.6.0.28            0xa51a0
> > > >             l [.] 0x00000000000a51a0
> > > >
> > > > On the other hand, plt symbols in other libraries are fine (memset@plt in
> > > > this case):
> > > >  >     0.17%  main2    /usr/lib64/libantlr4-runtime.so.4.8       0x4ed10
> > > >             l [.] memset@plt
> > > >
> > > > I dumped memcmp's .plt.rela entries in perf:
> > > > /usr/lib64/libantlr4-runtime.so.4.8: 154th addr=4e9d0 plt_off=4e020 hdr=10
> > > > entry=10
> > > > /usr/lib64/libstdc++.so.6.0.28: 772th addr=a1070 plt_off=9e020 hdr=10
> > > > entry=10
> > > >
> > > > The difference (offset) of stdc++'s memcmp is 0xa51a0 (correct) - 0xa1070
> > > > (perf's computed) = 0x4130.
> > > >
> > > > The problem is perf assumes nth entry of .plt.rela to correspond to nth
> > > > function in .plt, but memcmp is in .plt.sec in libstdc++.so:
> > > >
> > > >  >Relocation section '.rela.plt' at offset 0x97900 contains 1018 entries:
> > > >  >     Offset             Info             Type               Symbol's
> > > > Value  Symbol's Name + Addend
> > > >  > ...
> > > >  > 00000000001dc838  0000007800000007 R_X86_64_JUMP_SLOT
> > > > 0000000000000000 memcmp@GLIBC_2.2.5 + 0
> > > >
> > > > Perf does this with the rela entries:
> > > > https://github.com/torvalds/linux/blob/f5e6c330254ae691f6d7befe61c786eb5056007e/tools/perf/util/symbol-elf.c#L385
> > > >
> > > > It takes a symbol index from sym.r_info. Then it resolves its name from
> > > > .dynsym, appending "@plt" to it. Then this name is added to perf's symbol
> > > > table along with address which is computed as .rela.plt index multiplied by
> > > > entry size (shdr_plt.sh_entsize) plus plt header (shdr_plt.sh_entsize on
> > > > x86_64 too).
> > > >
> > > > And from this comes (almost) the offset above:
> > > >  >$ objdump -h /usr/lib64/libstdc++.so.6|grep -E ' .plt(\.sec)? '
> > > >  >  12 .plt          00003fb0  000000000009e020  000000000009e020
> > > > 0009e020  2**4
> > > >  >  14 .plt.sec      00003fa0  00000000000a2160  00000000000a2160
> > > > 000a2160  2**4
> > > >
> > > > 0xa2160-0x9e020 = 0x4140. I assume the 0x10 difference is that perf adds
> > > > shdr_plt.sh_entsize (0x10) to the offset to skip the first .plt entry
> > > > (header).
> > > >
> > > > Richard writes:
> > > > ======
> > > > .plt.sec is IIRC the "second" (sec) PLT entry - the one that will be used on
> > > > the second call (and on).  This is used / emitted for ELF object
> > > > instrumented for Intel CET.  The details escape me for the moment but I hope
> > > > the x86 ABI documents this (and the constraints) in detail.
> >
> > I just checked and the x86_64 psABI doesn't say anything about .plt.sec
> 
> The second PLT is documented in section 13.2 Dynamic Linking in x86-64
> psABI.  Please see elf_x86_64_get_synthetic_symtab in binutils for PLT symbol
> processing.

Hmm, google pointed me to https://gitlab.com/x86-psABIs/ and that
version does not have a section 13 (but the last is section 12 on MPX).
There's also references to a pdf which contain the section but
that's on github and the github page says gitlab is the home...
So I'm a bit confused here.

Richard.

-- 
Richard Biener <rguenther@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)

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

* Re: perf does not resolve plt symbols from libstdc++ right (.plt.sec problem)
  2021-03-29 13:06       ` Richard Biener
@ 2021-03-29 13:10         ` H.J. Lu
  2021-03-31  6:56           ` Jiri Slaby
  0 siblings, 1 reply; 7+ messages in thread
From: H.J. Lu @ 2021-03-29 13:10 UTC (permalink / raw)
  To: Richard Biener
  Cc: Jiri Slaby, Peter Zijlstra, Ingo Molnar,
	Arnaldo Carvalho de Melo, Mark Rutland, Alexander Shishkin,
	Jiri Olsa, Namhyung Kim, LKML

On Mon, Mar 29, 2021 at 6:06 AM Richard Biener <rguenther@suse.de> wrote:
>
> On Mon, 29 Mar 2021, H.J. Lu wrote:
>
> > On Mon, Mar 29, 2021 at 2:38 AM Richard Biener <rguenther@suse.de> wrote:
> > >
> > > On Mon, 29 Mar 2021, Jiri Slaby wrote:
> > >
> > > > Any ideas on this?
> > > >
> > > > On 11. 01. 21, 7:31, Jiri Slaby wrote:
> > > > > Hi,
> > > > >
> > > > > this e-mails is a follow-up of my report at:
> > > > > https://bugzilla.suse.com/show_bug.cgi?id=1180681
> > > > >
> > > > > There is a problem with *@plt symbols in some libraries, they are unresolved
> > > > > by perf (memcmp@plt in this case):
> > > > >  >     0.26%  main2    /usr/lib64/libstdc++.so.6.0.28            0xa51a0
> > > > >             l [.] 0x00000000000a51a0
> > > > >
> > > > > On the other hand, plt symbols in other libraries are fine (memset@plt in
> > > > > this case):
> > > > >  >     0.17%  main2    /usr/lib64/libantlr4-runtime.so.4.8       0x4ed10
> > > > >             l [.] memset@plt
> > > > >
> > > > > I dumped memcmp's .plt.rela entries in perf:
> > > > > /usr/lib64/libantlr4-runtime.so.4.8: 154th addr=4e9d0 plt_off=4e020 hdr=10
> > > > > entry=10
> > > > > /usr/lib64/libstdc++.so.6.0.28: 772th addr=a1070 plt_off=9e020 hdr=10
> > > > > entry=10
> > > > >
> > > > > The difference (offset) of stdc++'s memcmp is 0xa51a0 (correct) - 0xa1070
> > > > > (perf's computed) = 0x4130.
> > > > >
> > > > > The problem is perf assumes nth entry of .plt.rela to correspond to nth
> > > > > function in .plt, but memcmp is in .plt.sec in libstdc++.so:
> > > > >
> > > > >  >Relocation section '.rela.plt' at offset 0x97900 contains 1018 entries:
> > > > >  >     Offset             Info             Type               Symbol's
> > > > > Value  Symbol's Name + Addend
> > > > >  > ...
> > > > >  > 00000000001dc838  0000007800000007 R_X86_64_JUMP_SLOT
> > > > > 0000000000000000 memcmp@GLIBC_2.2.5 + 0
> > > > >
> > > > > Perf does this with the rela entries:
> > > > > https://github.com/torvalds/linux/blob/f5e6c330254ae691f6d7befe61c786eb5056007e/tools/perf/util/symbol-elf.c#L385
> > > > >
> > > > > It takes a symbol index from sym.r_info. Then it resolves its name from
> > > > > .dynsym, appending "@plt" to it. Then this name is added to perf's symbol
> > > > > table along with address which is computed as .rela.plt index multiplied by
> > > > > entry size (shdr_plt.sh_entsize) plus plt header (shdr_plt.sh_entsize on
> > > > > x86_64 too).
> > > > >
> > > > > And from this comes (almost) the offset above:
> > > > >  >$ objdump -h /usr/lib64/libstdc++.so.6|grep -E ' .plt(\.sec)? '
> > > > >  >  12 .plt          00003fb0  000000000009e020  000000000009e020
> > > > > 0009e020  2**4
> > > > >  >  14 .plt.sec      00003fa0  00000000000a2160  00000000000a2160
> > > > > 000a2160  2**4
> > > > >
> > > > > 0xa2160-0x9e020 = 0x4140. I assume the 0x10 difference is that perf adds
> > > > > shdr_plt.sh_entsize (0x10) to the offset to skip the first .plt entry
> > > > > (header).
> > > > >
> > > > > Richard writes:
> > > > > ======
> > > > > .plt.sec is IIRC the "second" (sec) PLT entry - the one that will be used on
> > > > > the second call (and on).  This is used / emitted for ELF object
> > > > > instrumented for Intel CET.  The details escape me for the moment but I hope
> > > > > the x86 ABI documents this (and the constraints) in detail.
> > >
> > > I just checked and the x86_64 psABI doesn't say anything about .plt.sec
> >
> > The second PLT is documented in section 13.2 Dynamic Linking in x86-64
> > psABI.  Please see elf_x86_64_get_synthetic_symtab in binutils for PLT symbol
> > processing.
>
> Hmm, google pointed me to https://gitlab.com/x86-psABIs/ and that
> version does not have a section 13 (but the last is section 12 on MPX).
> There's also references to a pdf which contain the section but
> that's on github and the github page says gitlab is the home...
> So I'm a bit confused here.
>

https://gitlab.com/x86-psABIs/x86-64-ABI/-/merge_requests/13


-- 
H.J.

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

* Re: perf does not resolve plt symbols from libstdc++ right (.plt.sec problem)
  2021-03-29 13:10         ` H.J. Lu
@ 2021-03-31  6:56           ` Jiri Slaby
  0 siblings, 0 replies; 7+ messages in thread
From: Jiri Slaby @ 2021-03-31  6:56 UTC (permalink / raw)
  To: H.J. Lu, Richard Biener
  Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim, LKML

On 29. 03. 21, 15:10, H.J. Lu wrote:
> On Mon, Mar 29, 2021 at 6:06 AM Richard Biener <rguenther@suse.de> wrote:
>>
>> On Mon, 29 Mar 2021, H.J. Lu wrote:
>>
>>> On Mon, Mar 29, 2021 at 2:38 AM Richard Biener <rguenther@suse.de> wrote:
>>>>
>>>> On Mon, 29 Mar 2021, Jiri Slaby wrote:
>>>>
>>>>> Any ideas on this?
>>>>>
>>>>> On 11. 01. 21, 7:31, Jiri Slaby wrote:
>>>>>> Hi,
>>>>>>
>>>>>> this e-mails is a follow-up of my report at:
>>>>>> https://bugzilla.suse.com/show_bug.cgi?id=1180681
>>>>>>
>>>>>> There is a problem with *@plt symbols in some libraries, they are unresolved
>>>>>> by perf (memcmp@plt in this case):
>>>>>>   >     0.26%  main2    /usr/lib64/libstdc++.so.6.0.28            0xa51a0
>>>>>>              l [.] 0x00000000000a51a0
>>>>>>
>>>>>> On the other hand, plt symbols in other libraries are fine (memset@plt in
>>>>>> this case):
>>>>>>   >     0.17%  main2    /usr/lib64/libantlr4-runtime.so.4.8       0x4ed10
>>>>>>              l [.] memset@plt
>>>>>>
>>>>>> I dumped memcmp's .plt.rela entries in perf:
>>>>>> /usr/lib64/libantlr4-runtime.so.4.8: 154th addr=4e9d0 plt_off=4e020 hdr=10
>>>>>> entry=10
>>>>>> /usr/lib64/libstdc++.so.6.0.28: 772th addr=a1070 plt_off=9e020 hdr=10
>>>>>> entry=10
>>>>>>
>>>>>> The difference (offset) of stdc++'s memcmp is 0xa51a0 (correct) - 0xa1070
>>>>>> (perf's computed) = 0x4130.
>>>>>>
>>>>>> The problem is perf assumes nth entry of .plt.rela to correspond to nth
>>>>>> function in .plt, but memcmp is in .plt.sec in libstdc++.so:
>>>>>>
>>>>>>   >Relocation section '.rela.plt' at offset 0x97900 contains 1018 entries:
>>>>>>   >     Offset             Info             Type               Symbol's
>>>>>> Value  Symbol's Name + Addend
>>>>>>   > ...
>>>>>>   > 00000000001dc838  0000007800000007 R_X86_64_JUMP_SLOT
>>>>>> 0000000000000000 memcmp@GLIBC_2.2.5 + 0
>>>>>>
>>>>>> Perf does this with the rela entries:
>>>>>> https://github.com/torvalds/linux/blob/f5e6c330254ae691f6d7befe61c786eb5056007e/tools/perf/util/symbol-elf.c#L385
>>>>>>
>>>>>> It takes a symbol index from sym.r_info. Then it resolves its name from
>>>>>> .dynsym, appending "@plt" to it. Then this name is added to perf's symbol
>>>>>> table along with address which is computed as .rela.plt index multiplied by
>>>>>> entry size (shdr_plt.sh_entsize) plus plt header (shdr_plt.sh_entsize on
>>>>>> x86_64 too).
>>>>>>
>>>>>> And from this comes (almost) the offset above:
>>>>>>   >$ objdump -h /usr/lib64/libstdc++.so.6|grep -E ' .plt(\.sec)? '
>>>>>>   >  12 .plt          00003fb0  000000000009e020  000000000009e020
>>>>>> 0009e020  2**4
>>>>>>   >  14 .plt.sec      00003fa0  00000000000a2160  00000000000a2160
>>>>>> 000a2160  2**4
>>>>>>
>>>>>> 0xa2160-0x9e020 = 0x4140. I assume the 0x10 difference is that perf adds
>>>>>> shdr_plt.sh_entsize (0x10) to the offset to skip the first .plt entry
>>>>>> (header).
>>>>>>
>>>>>> Richard writes:
>>>>>> ======
>>>>>> .plt.sec is IIRC the "second" (sec) PLT entry - the one that will be used on
>>>>>> the second call (and on).  This is used / emitted for ELF object
>>>>>> instrumented for Intel CET.  The details escape me for the moment but I hope
>>>>>> the x86 ABI documents this (and the constraints) in detail.
>>>>
>>>> I just checked and the x86_64 psABI doesn't say anything about .plt.sec
>>>
>>> The second PLT is documented in section 13.2 Dynamic Linking in x86-64
>>> psABI.  Please see elf_x86_64_get_synthetic_symtab in binutils for PLT symbol
>>> processing.
>>
>> Hmm, google pointed me to https://gitlab.com/x86-psABIs/ and that
>> version does not have a section 13 (but the last is section 12 on MPX).
>> There's also references to a pdf which contain the section but
>> that's on github and the github page says gitlab is the home...
>> So I'm a bit confused here.
>>
> 
> https://gitlab.com/x86-psABIs/x86-64-ABI/-/merge_requests/13

Ok, so it talks only about GOT:
===
When the IBT-enabled procedure linkage table is used, the initial value 
of the global offset table entry for the external function is the 
address of the corresponding entry of the second procedure linkage table.
===

GOTs are now related to .plt.sec. But my question about .plt.rela 
remains unanswered by the above:
 > The problem is perf assumes nth entry of .plt.rela to correspond to nth
 > function in .plt, but memcmp is in .plt.sec in libstdc++.so

So how one finds out whether .rela entries belong to .plt or .plt.sec? 
Or should we assume that with .plt.sec, .plt.rela always points to .plt.sec?

thanks,
-- 
js
suse labs

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

end of thread, other threads:[~2021-03-31  6:57 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-11  6:31 perf does not resolve plt symbols from libstdc++ right (.plt.sec problem) Jiri Slaby
2021-03-29  9:09 ` Jiri Slaby
2021-03-29  9:38   ` Richard Biener
2021-03-29 12:52     ` H.J. Lu
2021-03-29 13:06       ` Richard Biener
2021-03-29 13:10         ` H.J. Lu
2021-03-31  6:56           ` Jiri Slaby

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).