Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751258AbdFFBru (ORCPT ); Mon, 5 Jun 2017 21:47:50 -0400 Received: from mail-wm0-f67.google.com ([74.125.82.67]:35630 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751107AbdFFBrs (ORCPT ); Mon, 5 Jun 2017 21:47:48 -0400 MIME-Version: 1.0 In-Reply-To: <1496622849-21877-1-git-send-email-huawei.libin@huawei.com> References: <1496622849-21877-1-git-send-email-huawei.libin@huawei.com> From: Namhyung Kim Date: Tue, 6 Jun 2017 10:47:26 +0900 X-Google-Sender-Auth: oexvCakh4cPv6vWxstHpf-jP4Qs Message-ID: Subject: Re: [PATCH] perf symbols: Fix plt entry calculation for ARM and AARCH64 To: Li Bin Cc: "linux-kernel@vger.kernel.org" , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Alexander Shishkin , Masami Hiramatsu , Hemant Kumar , alexis.berlemont@gmail.com, dtolnay@gmail.com, Milian Wolff , Wang Nan , guohanjun@huawei.com, zhangmengting@huawei.com Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 6713 Lines: 160 On Mon, Jun 5, 2017 at 9:34 AM, Li Bin wrote: > On x86, the plt header size is as same as the plt entry size, and > can be identified from shdr's sh_entsize of the plt. > But we cann't assume that the sh_entsize of the plt shdr is always > the plt entry size in all architecture, and the plt header size may > be not as same as the plt entry size in some architecure. > > On ARM, the plt header size is 20 bytes and the plt entry size is 12 > bytes(don't consider the FOUR_WORD_PLT case) > that refer to the binutils implementation. > plt section is as follows: > > Disassembly of section .plt: > 000004a0 <__cxa_finalize@plt-0x14>: > 4a0: e52de004 push {lr} ; (str lr, [sp, #-4]!) > 4a4: e59fe004 ldr lr, [pc, #4] ; 4b0 <_init+0x1c> > 4a8: e08fe00e add lr, pc, lr > 4ac: e5bef008 ldr pc, [lr, #8]! > 4b0: 00008424 .word 0x00008424 > > 000004b4 <__cxa_finalize@plt>: > 4b4: e28fc600 add ip, pc, #0, 12 > 4b8: e28cca08 add ip, ip, #8, 20 ; 0x8000 > 4bc: e5bcf424 ldr pc, [ip, #1060]! ; 0x424 > > 000004c0 : > 4c0: e28fc600 add ip, pc, #0, 12 > 4c4: e28cca08 add ip, ip, #8, 20 ; 0x8000 > 4c8: e5bcf41c ldr pc, [ip, #1052]! ; 0x41c > > On AARCH64, the plt header size is 32 bytes and the plt entry size is > 16 bytes. > plt section is as follows: > > Disassembly of section .plt: > 0000000000000560 <__cxa_finalize@plt-0x20>: > 560: a9bf7bf0 stp x16, x30, [sp,#-16]! > 564: 90000090 adrp x16, 10000 <__FRAME_END__+0xf8a8> > 568: f944be11 ldr x17, [x16,#2424] > 56c: 9125e210 add x16, x16, #0x978 > 570: d61f0220 br x17 > 574: d503201f nop > 578: d503201f nop > 57c: d503201f nop > > 0000000000000580 <__cxa_finalize@plt>: > 580: 90000090 adrp x16, 10000 <__FRAME_END__+0xf8a8> > 584: f944c211 ldr x17, [x16,#2432] > 588: 91260210 add x16, x16, #0x980 > 58c: d61f0220 br x17 > > 0000000000000590 <__gmon_start__@plt>: > 590: 90000090 adrp x16, 10000 <__FRAME_END__+0xf8a8> > 594: f944c611 ldr x17, [x16,#2440] > 598: 91262210 add x16, x16, #0x988 > 59c: d61f0220 br x17 > > NOTES: > In addition to ARM and AARCH64, other architectures, such as > s390/alpha/mips/parisc/poperpc/sh/sparc/xtensa also need to consider > this issue. > > Signed-off-by: Li Bin I don't know other archs, but this change looks ok to me.. Acked-by: Namhyung Kim Thanks, Namhyung > --- > tools/perf/util/symbol-elf.c | 27 ++++++++++++++++++++++----- > 1 file changed, 22 insertions(+), 5 deletions(-) > > diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c > index e7ee47f..1bccf71 100644 > --- a/tools/perf/util/symbol-elf.c > +++ b/tools/perf/util/symbol-elf.c > @@ -259,7 +259,7 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map * > { > uint32_t nr_rel_entries, idx; > GElf_Sym sym; > - u64 plt_offset; > + u64 plt_offset, plt_header_size, plt_entry_size; > GElf_Shdr shdr_plt; > struct symbol *f; > GElf_Shdr shdr_rel_plt, shdr_dynsym; > @@ -326,6 +326,23 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map * > > nr_rel_entries = shdr_rel_plt.sh_size / shdr_rel_plt.sh_entsize; > plt_offset = shdr_plt.sh_offset; > + switch (ehdr.e_machine) { > + case EM_ARM: > + plt_header_size = 20; > + plt_entry_size = 12; > + break; > + > + case EM_AARCH64: > + plt_header_size = 32; > + plt_entry_size = 16; > + break; > + > + default: /* FIXME: s390/alpha/mips/parisc/poperpc/sh/sparc/xtensa need to be checked */ > + plt_header_size = shdr_plt.sh_entsize; > + plt_entry_size = shdr_plt.sh_entsize; > + break; > + } > + plt_offset += plt_header_size; > > if (shdr_rel_plt.sh_type == SHT_RELA) { > GElf_Rela pos_mem, *pos; > @@ -335,7 +352,6 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map * > const char *elf_name = NULL; > char *demangled = NULL; > symidx = GELF_R_SYM(pos->r_info); > - plt_offset += shdr_plt.sh_entsize; > gelf_getsym(syms, symidx, &sym); > > elf_name = elf_sym__name(&sym, symstrs); > @@ -346,11 +362,12 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map * > "%s@plt", elf_name); > free(demangled); > > - f = symbol__new(plt_offset, shdr_plt.sh_entsize, > + f = symbol__new(plt_offset, plt_entry_size, > STB_GLOBAL, sympltname); > if (!f) > goto out_elf_end; > > + plt_offset += plt_entry_size; > symbols__insert(&dso->symbols[map->type], f); > ++nr; > } > @@ -361,7 +378,6 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map * > const char *elf_name = NULL; > char *demangled = NULL; > symidx = GELF_R_SYM(pos->r_info); > - plt_offset += shdr_plt.sh_entsize; > gelf_getsym(syms, symidx, &sym); > > elf_name = elf_sym__name(&sym, symstrs); > @@ -372,11 +388,12 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map * > "%s@plt", elf_name); > free(demangled); > > - f = symbol__new(plt_offset, shdr_plt.sh_entsize, > + f = symbol__new(plt_offset, plt_entry_size, > STB_GLOBAL, sympltname); > if (!f) > goto out_elf_end; > > + plt_offset += plt_entry_size; > symbols__insert(&dso->symbols[map->type], f); > ++nr; > } > -- > 1.7.12.4 >