Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1301355 > unrolled thread

[bug] wrong result of android callchain

Started byHe Kuang <hekuang@huawei.com>
First post2016-01-05 10:20 +0100
Last post2016-01-12 04:10 +0100
Articles 6 — 4 participants

Back to article view | Back to linux.kernel


Contents

  [bug] wrong result of android callchain He Kuang <hekuang@huawei.com> - 2016-01-05 10:20 +0100
    Re: [bug] wrong result of android callchain Peter Zijlstra <peterz@infradead.org> - 2016-01-05 11:30 +0100
      Re: [bug] wrong result of android callchain Will Deacon <will.deacon@arm.com> - 2016-01-05 12:20 +0100
        [PATCH] perf symbols: Fix wrong symbol offset according to p_addr He Kuang <hekuang@huawei.com> - 2016-01-06 09:30 +0100
          Re: [PATCH] perf symbols: Fix wrong symbol offset according to p_addr Ingo Molnar <mingo@kernel.org> - 2016-01-11 12:30 +0100
            [PATCH v2] perf symbols: Fix wrong symbol offset according to p_addr He Kuang <hekuang@huawei.com> - 2016-01-12 04:10 +0100

#1301355 — [bug] wrong result of android callchain

FromHe Kuang <hekuang@huawei.com>
Date2016-01-05 10:20 +0100
Subject[bug] wrong result of android callchain
Message-ID<qNvWy-8rN-23@gated-at.bofh.it>
I found a wrong result of aarch64 callchain when using perf script on
a android phone.

Here's the callchain record fragment from the output of perf script:

   init   369 [002]   339.970607: raw_syscalls:sys_enter: NR 22 (b, 7fd9e360a0, 10, ffffffff, 0, 8)
                      ...
                    230ac [unknown] (/system/lib64/libsurfaceflinger.so)
                     11a0 main (/system/bin/surfaceflinger)
                    1c3fc __libc_init (/system/lib64/libc.so)
                      fd0 _start (/system/bin/surfaceflinger)
                     29ec __dl__start (/system/bin/linker64)

The fault occured in the '[unknown]' line, from objdump result of
/system/bin/surfaceflinger, we can see the branch instruction before
0x11a0:

  # objdump /system/bin/surfaceflinger
     1198:       f9400fe0        ldr     x0, [sp,#24]
     119c:       97ffff05        bl      db0 <_ZN7android14SurfaceFlinger3runEv@plt>
     11a0:       f9400be8        ldr     x8, [sp,#16]
     11a4:       b40000c8        cbz     x8, 11bc <main+0x150>

The function '_ZN7android14SurfaceFlinger3runEv' is located at 0x3a094
~ 0x3a0ac in libsurfaceflinger.so, but perf misparsed that value to
0x230ac:

  # objdump libsurfaceflinger.so
   000000000003a094 <_ZN7android14SurfaceFlinger3runEv>:
     3a094:       a9be4ff4        stp     x20, x19, [sp,#-32]!
     3a098:       a9017bfd        stp     x29, x30, [sp,#16]
     3a09c:       910043fd        add     x29, sp, #0x10
     3a0a0:       910c0013        add     x19, x0, #0x300
     3a0a4:       aa1303e0        mov     x0, x19
     3a0a8:       97fff12f        bl      36564 <_ZN7android12MessageQueue11waitMessageEv>
     3a0ac:       17fffffe        b       3a0a4 <_ZN7android14SurfaceFlinger3runEv+0x10>

There's a difference of 0x17000 between those two offsets, it seems
that this value is the VirtAddr of this dynamic library.

  # readelf -a libsurfaceflinger.so
   Program Headers:
     Type           Offset             VirtAddr           PhysAddr
                    FileSiz            MemSiz              Flags  Align
     LOAD           0x0000000000000000 0x0000000000017000 0x0000000000017000
                    0x0000000000057258 0x0000000000057258  R E    1000


                                                    

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1301408

FromPeter Zijlstra <peterz@infradead.org>
Date2016-01-05 11:30 +0100
Message-ID<qNx2i-Ku-17@gated-at.bofh.it>
In reply to#1301355
On Tue, Jan 05, 2016 at 05:14:37PM +0800, He Kuang wrote:
> I found a wrong result of aarch64 callchain when using perf script on
> a android phone.

Might help to include the AARGH64 people then.. seeing I have no clue
about all that. Cc's added, email preserved etc..

> 
> Here's the callchain record fragment from the output of perf script:
> 
>   init   369 [002]   339.970607: raw_syscalls:sys_enter: NR 22 (b, 7fd9e360a0, 10, ffffffff, 0, 8)
>                      ...
>                    230ac [unknown] (/system/lib64/libsurfaceflinger.so)
>                     11a0 main (/system/bin/surfaceflinger)
>                    1c3fc __libc_init (/system/lib64/libc.so)
>                      fd0 _start (/system/bin/surfaceflinger)
>                     29ec __dl__start (/system/bin/linker64)
> 
> The fault occured in the '[unknown]' line, from objdump result of
> /system/bin/surfaceflinger, we can see the branch instruction before
> 0x11a0:
> 
>  # objdump /system/bin/surfaceflinger
>     1198:       f9400fe0        ldr     x0, [sp,#24]
>     119c:       97ffff05        bl      db0 <_ZN7android14SurfaceFlinger3runEv@plt>
>     11a0:       f9400be8        ldr     x8, [sp,#16]
>     11a4:       b40000c8        cbz     x8, 11bc <main+0x150>
> 
> The function '_ZN7android14SurfaceFlinger3runEv' is located at 0x3a094
> ~ 0x3a0ac in libsurfaceflinger.so, but perf misparsed that value to
> 0x230ac:
> 
>  # objdump libsurfaceflinger.so
>   000000000003a094 <_ZN7android14SurfaceFlinger3runEv>:
>     3a094:       a9be4ff4        stp     x20, x19, [sp,#-32]!
>     3a098:       a9017bfd        stp     x29, x30, [sp,#16]
>     3a09c:       910043fd        add     x29, sp, #0x10
>     3a0a0:       910c0013        add     x19, x0, #0x300
>     3a0a4:       aa1303e0        mov     x0, x19
>     3a0a8:       97fff12f        bl      36564 <_ZN7android12MessageQueue11waitMessageEv>
>     3a0ac:       17fffffe        b       3a0a4 <_ZN7android14SurfaceFlinger3runEv+0x10>
> 
> There's a difference of 0x17000 between those two offsets, it seems
> that this value is the VirtAddr of this dynamic library.
> 
>  # readelf -a libsurfaceflinger.so
>   Program Headers:
>     Type           Offset             VirtAddr           PhysAddr
>                    FileSiz            MemSiz              Flags  Align
>     LOAD           0x0000000000000000 0x0000000000017000 0x0000000000017000
>                    0x0000000000057258 0x0000000000057258  R E    1000
> 
> 
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1301449

FromWill Deacon <will.deacon@arm.com>
Date2016-01-05 12:20 +0100
Message-ID<qNxOF-1jL-7@gated-at.bofh.it>
In reply to#1301408
On Tue, Jan 05, 2016 at 11:20:55AM +0100, Peter Zijlstra wrote:
> On Tue, Jan 05, 2016 at 05:14:37PM +0800, He Kuang wrote:
> > I found a wrong result of aarch64 callchain when using perf script on
> > a android phone.
> 
> Might help to include the AARGH64 people then.. seeing I have no clue
> about all that. Cc's added, email preserved etc..

It looks like the issue is in the perf tool, where it fails to resolve
the address to a symbol correctly.

> > 
> > Here's the callchain record fragment from the output of perf script:
> > 
> >   init   369 [002]   339.970607: raw_syscalls:sys_enter: NR 22 (b, 7fd9e360a0, 10, ffffffff, 0, 8)
> >                      ...
> >                    230ac [unknown] (/system/lib64/libsurfaceflinger.so)
> >                     11a0 main (/system/bin/surfaceflinger)
> >                    1c3fc __libc_init (/system/lib64/libc.so)
> >                      fd0 _start (/system/bin/surfaceflinger)
> >                     29ec __dl__start (/system/bin/linker64)
> > 
> > The fault occured in the '[unknown]' line, from objdump result of
> > /system/bin/surfaceflinger, we can see the branch instruction before
> > 0x11a0:
> > 
> >  # objdump /system/bin/surfaceflinger
> >     1198:       f9400fe0        ldr     x0, [sp,#24]
> >     119c:       97ffff05        bl      db0 <_ZN7android14SurfaceFlinger3runEv@plt>
> >     11a0:       f9400be8        ldr     x8, [sp,#16]
> >     11a4:       b40000c8        cbz     x8, 11bc <main+0x150>
> > 
> > The function '_ZN7android14SurfaceFlinger3runEv' is located at 0x3a094
> > ~ 0x3a0ac in libsurfaceflinger.so, but perf misparsed that value to
> > 0x230ac:
> > 
> >  # objdump libsurfaceflinger.so
> >   000000000003a094 <_ZN7android14SurfaceFlinger3runEv>:
> >     3a094:       a9be4ff4        stp     x20, x19, [sp,#-32]!
> >     3a098:       a9017bfd        stp     x29, x30, [sp,#16]
> >     3a09c:       910043fd        add     x29, sp, #0x10
> >     3a0a0:       910c0013        add     x19, x0, #0x300
> >     3a0a4:       aa1303e0        mov     x0, x19
> >     3a0a8:       97fff12f        bl      36564 <_ZN7android12MessageQueue11waitMessageEv>
> >     3a0ac:       17fffffe        b       3a0a4 <_ZN7android14SurfaceFlinger3runEv+0x10>
> > 
> > There's a difference of 0x17000 between those two offsets, it seems
> > that this value is the VirtAddr of this dynamic library.
> > 
> >  # readelf -a libsurfaceflinger.so
> >   Program Headers:
> >     Type           Offset             VirtAddr           PhysAddr
> >                    FileSiz            MemSiz              Flags  Align
> >     LOAD           0x0000000000000000 0x0000000000017000 0x0000000000017000
> >                    0x0000000000057258 0x0000000000057258  R E    1000

This reminds me of:

  http://lkml.kernel.org/r/1435162623-20075-1-git-send-email-will.deacon@arm.com

but that was all vdso-specific. Can you look at what gets passed to objdump?

Will
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1302463 — [PATCH] perf symbols: Fix wrong symbol offset according to p_addr

FromHe Kuang <hekuang@huawei.com>
Date2016-01-06 09:30 +0100
Subject[PATCH] perf symbols: Fix wrong symbol offset according to p_addr
Message-ID<qNRDJ-71N-29@gated-at.bofh.it>
In reply to#1301449
Perf missed the 'VirtAddr' value in elf program_headers when adjusting
symbol address for dynamic libraries. This patch considers the p_addr
value and gets the right symbol offset.

Before this patch, some symbols can not be right parsed on android phone:

  init   369 [002]   339.970607: raw_syscalls:sys_enter: NR 22 (b, 7fd9e360a0, 10, ffffffff, 0, 8)
                     ...
                   230ac [unknown] (/system/lib64/libsurfaceflinger.so)
                    11a0 main (/system/bin/surfaceflinger)
                   1c3fc __libc_init (/system/lib64/libc.so)
                     fd0 _start (/system/bin/surfaceflinger)
                    29ec __dl__start (/system/bin/linker64)

After this patch:

  init   369 [002]   339.970607: raw_syscalls:sys_enter: NR 22 (b, 7fd9e360a0, 10, ffffffff, 0, 8)
                     ...
                   3a0ac _ZN7android14SurfaceFlinger3runEv (/system/lib64/libsurfaceflinger.so)
                    11a0 main (/system/bin/surfaceflinger)
                   1c3fc __libc_init (/system/lib64/libc.so)
                     fd0 _start (/system/bin/surfaceflinger)
                    29ec __dl__start (/system/bin/linker64)

Signed-off-by: He Kuang <hekuang@huawei.com>
---
 tools/perf/util/dso.c        |  6 ++++++
 tools/perf/util/dso.h        |  1 +
 tools/perf/util/event.c      |  6 +++++-
 tools/perf/util/map.h        |  7 +++++--
 tools/perf/util/symbol-elf.c | 20 ++++++++++++++++++++
 5 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index e8e9a9d..93bf13a 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -1063,6 +1063,7 @@ struct dso *dso__new(const char *name)
 		dso->needs_swap = DSO_SWAP__UNSET;
 		RB_CLEAR_NODE(&dso->rb_node);
 		dso->root = NULL;
+		dso->vaddr = 0;
 		INIT_LIST_HEAD(&dso->node);
 		INIT_LIST_HEAD(&dso->data.open_entry);
 		pthread_mutex_init(&dso->lock, NULL);
@@ -1367,3 +1368,8 @@ int dso__strerror_load(struct dso *dso, char *buf, size_t buflen)
 	scnprintf(buf, buflen, "%s", dso_load__error_str[idx]);
 	return 0;
 }
+
+u64 dso__get_vaddr(struct dso *dso)
+{
+	return dso->vaddr;
+}
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index 45ec4d0..b6c894f 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -166,6 +166,7 @@ struct dso {
 	const char	 *long_name;
 	u16		 long_name_len;
 	u16		 short_name_len;
+	u64		vaddr;
 	void		*dwfl;			/* DWARF debug info */
 	struct auxtrace_cache *auxtrace_cache;
 
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index cd61bb1..ef964c0 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -1273,8 +1273,12 @@ try_again:
 		 * Kernel maps might be changed when loading symbols so loading
 		 * must be done prior to using kernel maps.
 		 */
+		map__load(al->map, machine->symbol_filter);
+
+		/* exclude kernel kallsyms */
 		if (load_map)
-			map__load(al->map, machine->symbol_filter);
+			al->map->dso->vaddr = 0;
+
 		al->addr = al->map->map_ip(al->map, al->addr);
 	}
 }
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 7309d64..68ab703 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -86,14 +86,17 @@ void map_groups__put(struct map_groups *mg);
 struct kmap *map__kmap(struct map *map);
 struct map_groups *map__kmaps(struct map *map);
 
+u64 dso__get_vaddr(struct dso *dso);
 static inline u64 map__map_ip(struct map *map, u64 ip)
 {
-	return ip - map->start + map->pgoff;
+	return ip - map->start + map->pgoff +
+		dso__get_vaddr(map->dso);
 }
 
 static inline u64 map__unmap_ip(struct map *map, u64 ip)
 {
-	return ip + map->start - map->pgoff;
+	return ip + map->start - map->pgoff -
+		dso__get_vaddr(map->dso);
 }
 
 static inline u64 identity__map_ip(struct map *map __maybe_unused, u64 ip)
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 562b8eb..de0129f 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -15,6 +15,8 @@
 #define EM_AARCH64	183  /* ARM 64 bit */
 #endif
 
+static int elf_read_maps_ex(Elf * elf, bool exe, mapfn_t mapfn, void *data,
+			    struct map *map);
 
 #ifdef HAVE_CPLUS_DEMANGLE_SUPPORT
 extern char *cplus_demangle(const char *, int);
@@ -831,6 +833,10 @@ int dso__load_sym(struct dso *dso, struct map *map,
 	sec = syms_ss->symtab;
 	shdr = syms_ss->symshdr;
 
+	err = elf_read_maps_ex(elf, ehdr.e_type == ET_EXEC ||
+			       ehdr.e_type == ET_REL,
+			       NULL, NULL, map);
+
 	if (runtime_ss->opdsec)
 		opddata = elf_rawdata(runtime_ss->opdsec, NULL);
 
@@ -1116,6 +1122,13 @@ out_elf_end:
 
 static int elf_read_maps(Elf *elf, bool exe, mapfn_t mapfn, void *data)
 {
+
+	return elf_read_maps_ex(elf, exe, mapfn, data, NULL);
+}
+
+static int elf_read_maps_ex(Elf *elf, bool exe, mapfn_t mapfn, void *data,
+			    struct map *map)
+{
 	GElf_Phdr phdr;
 	size_t i, phdrnum;
 	int err;
@@ -1135,10 +1148,17 @@ static int elf_read_maps(Elf *elf, bool exe, mapfn_t mapfn, void *data)
 		} else {
 			if (!(phdr.p_flags & PF_R))
 				continue;
+			if (map && (phdr.p_flags & PF_X))
+				map->dso->vaddr = phdr.p_vaddr;
 		}
+
 		sz = min(phdr.p_memsz, phdr.p_filesz);
 		if (!sz)
 			continue;
+
+		if (!mapfn)
+			continue;
+
 		err = mapfn(phdr.p_vaddr, sz, phdr.p_offset, data);
 		if (err)
 			return err;
-- 
1.8.5.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1306098 — Re: [PATCH] perf symbols: Fix wrong symbol offset according to p_addr

FromIngo Molnar <mingo@kernel.org>
Date2016-01-11 12:30 +0100
SubjectRe: [PATCH] perf symbols: Fix wrong symbol offset according to p_addr
Message-ID<qPIPE-1Dk-19@gated-at.bofh.it>
In reply to#1302463
* He Kuang <hekuang@huawei.com> wrote:

> Perf missed the 'VirtAddr' value in elf program_headers when adjusting
> symbol address for dynamic libraries. This patch considers the p_addr
> value and gets the right symbol offset.

s/gets/calculates

> 
> Before this patch, some symbols can not be right parsed on android phone:

s/Before this patch, some symbols are not parsed correctly on android phones:

> 
>   init   369 [002]   339.970607: raw_syscalls:sys_enter: NR 22 (b, 7fd9e360a0, 10, ffffffff, 0, 8)
>                      ...
>                    230ac [unknown] (/system/lib64/libsurfaceflinger.so)
>                     11a0 main (/system/bin/surfaceflinger)
>                    1c3fc __libc_init (/system/lib64/libc.so)
>                      fd0 _start (/system/bin/surfaceflinger)
>                     29ec __dl__start (/system/bin/linker64)
> 
> After this patch:
> 
>   init   369 [002]   339.970607: raw_syscalls:sys_enter: NR 22 (b, 7fd9e360a0, 10, ffffffff, 0, 8)
>                      ...
>                    3a0ac _ZN7android14SurfaceFlinger3runEv (/system/lib64/libsurfaceflinger.so)
>                     11a0 main (/system/bin/surfaceflinger)
>                    1c3fc __libc_init (/system/lib64/libc.so)
>                      fd0 _start (/system/bin/surfaceflinger)
>                     29ec __dl__start (/system/bin/linker64)

> --- a/tools/perf/util/dso.h
> +++ b/tools/perf/util/dso.h
> @@ -166,6 +166,7 @@ struct dso {
>  	const char	 *long_name;
>  	u16		 long_name_len;
>  	u16		 short_name_len;
> +	u64		vaddr;
>  	void		*dwfl;			/* DWARF debug info */

btw., looks like there's some extra spaces in front of those other field 
definitions.

Also, might make sense to describe what 'vaddr' stands for precisely, the naming 
is pretty ambiguous.

Thanks,

	Ingo

[toc] | [prev] | [next] | [standalone]


#1306954 — [PATCH v2] perf symbols: Fix wrong symbol offset according to p_addr

FromHe Kuang <hekuang@huawei.com>
Date2016-01-12 04:10 +0100
Subject[PATCH v2] perf symbols: Fix wrong symbol offset according to p_addr
Message-ID<qPXvk-3n8-5@gated-at.bofh.it>
In reply to#1306098
Perf missed the 'VirtAddr' value in elf program_headers when adjusting
symbol address for dynamic libraries. This patch considers the p_addr
value and calculates the right symbol offset.

Before this patch, some symbols are not parsed correctly on android phone:

  init   369 [002]   339.970607: raw_syscalls:sys_enter: NR 22 (b, 7fd9e360a0, 10, ffffffff, 0, 8)
                     ...
                   230ac [unknown] (/system/lib64/libsurfaceflinger.so)
                    11a0 main (/system/bin/surfaceflinger)
                   1c3fc __libc_init (/system/lib64/libc.so)
                     fd0 _start (/system/bin/surfaceflinger)
                    29ec __dl__start (/system/bin/linker64)

After this patch:

  init   369 [002]   339.970607: raw_syscalls:sys_enter: NR 22 (b, 7fd9e360a0, 10, ffffffff, 0, 8)
                     ...
                   3a0ac _ZN7android14SurfaceFlinger3runEv (/system/lib64/libsurfaceflinger.so)
                    11a0 main (/system/bin/surfaceflinger)
                   1c3fc __libc_init (/system/lib64/libc.so)
                     fd0 _start (/system/bin/surfaceflinger)
                    29ec __dl__start (/system/bin/linker64)

Signed-off-by: He Kuang <hekuang@huawei.com>
---

Patch v1 to v2:
  - Modify commit message by following Ingo's suggestion.
  - Change ambiguous virable name 'vaddr' to 'load_virtaddr'.
  
---
 tools/perf/util/dso.c        |  6 ++++++
 tools/perf/util/dso.h        |  3 ++-
 tools/perf/util/event.c      |  6 +++++-
 tools/perf/util/map.h        |  7 +++++--
 tools/perf/util/symbol-elf.c | 20 ++++++++++++++++++++
 5 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index e8e9a9d..afc51ce 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -1063,6 +1063,7 @@ struct dso *dso__new(const char *name)
 		dso->needs_swap = DSO_SWAP__UNSET;
 		RB_CLEAR_NODE(&dso->rb_node);
 		dso->root = NULL;
+		dso->load_virtaddr = 0;
 		INIT_LIST_HEAD(&dso->node);
 		INIT_LIST_HEAD(&dso->data.open_entry);
 		pthread_mutex_init(&dso->lock, NULL);
@@ -1367,3 +1368,8 @@ int dso__strerror_load(struct dso *dso, char *buf, size_t buflen)
 	scnprintf(buf, buflen, "%s", dso_load__error_str[idx]);
 	return 0;
 }
+
+u64 dso__get_load_virtaddr(struct dso *dso)
+{
+	return dso->load_virtaddr;
+}
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index 45ec4d0..2a03b87 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -166,7 +166,8 @@ struct dso {
 	const char	 *long_name;
 	u16		 long_name_len;
 	u16		 short_name_len;
-	void		*dwfl;			/* DWARF debug info */
+	u64		 load_virtaddr;		/* Load virtual address */
+	void		 *dwfl;			/* DWARF debug info */
 	struct auxtrace_cache *auxtrace_cache;
 
 	/* dso data file */
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index cd61bb1..7f1dbdf 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -1273,8 +1273,12 @@ try_again:
 		 * Kernel maps might be changed when loading symbols so loading
 		 * must be done prior to using kernel maps.
 		 */
+		map__load(al->map, machine->symbol_filter);
+
+		/* exclude kernel kallsyms */
 		if (load_map)
-			map__load(al->map, machine->symbol_filter);
+			al->map->dso->load_virtaddr = 0;
+
 		al->addr = al->map->map_ip(al->map, al->addr);
 	}
 }
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 7309d64..db284a4 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -86,14 +86,17 @@ void map_groups__put(struct map_groups *mg);
 struct kmap *map__kmap(struct map *map);
 struct map_groups *map__kmaps(struct map *map);
 
+u64 dso__get_load_virtaddr(struct dso *dso);
 static inline u64 map__map_ip(struct map *map, u64 ip)
 {
-	return ip - map->start + map->pgoff;
+	return ip - map->start + map->pgoff +
+		dso__get_load_virtaddr(map->dso);
 }
 
 static inline u64 map__unmap_ip(struct map *map, u64 ip)
 {
-	return ip + map->start - map->pgoff;
+	return ip + map->start - map->pgoff -
+		dso__get_load_virtaddr(map->dso);
 }
 
 static inline u64 identity__map_ip(struct map *map __maybe_unused, u64 ip)
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 562b8eb..9a02b3e 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -15,6 +15,8 @@
 #define EM_AARCH64	183  /* ARM 64 bit */
 #endif
 
+static int elf_read_maps_ex(Elf * elf, bool exe, mapfn_t mapfn, void *data,
+			    struct map *map);
 
 #ifdef HAVE_CPLUS_DEMANGLE_SUPPORT
 extern char *cplus_demangle(const char *, int);
@@ -831,6 +833,10 @@ int dso__load_sym(struct dso *dso, struct map *map,
 	sec = syms_ss->symtab;
 	shdr = syms_ss->symshdr;
 
+	err = elf_read_maps_ex(elf, ehdr.e_type == ET_EXEC ||
+			       ehdr.e_type == ET_REL,
+			       NULL, NULL, map);
+
 	if (runtime_ss->opdsec)
 		opddata = elf_rawdata(runtime_ss->opdsec, NULL);
 
@@ -1116,6 +1122,13 @@ out_elf_end:
 
 static int elf_read_maps(Elf *elf, bool exe, mapfn_t mapfn, void *data)
 {
+
+	return elf_read_maps_ex(elf, exe, mapfn, data, NULL);
+}
+
+static int elf_read_maps_ex(Elf *elf, bool exe, mapfn_t mapfn, void *data,
+			    struct map *map)
+{
 	GElf_Phdr phdr;
 	size_t i, phdrnum;
 	int err;
@@ -1135,10 +1148,17 @@ static int elf_read_maps(Elf *elf, bool exe, mapfn_t mapfn, void *data)
 		} else {
 			if (!(phdr.p_flags & PF_R))
 				continue;
+			if (map && (phdr.p_flags & PF_X))
+				map->dso->load_virtaddr = phdr.p_vaddr;
 		}
+
 		sz = min(phdr.p_memsz, phdr.p_filesz);
 		if (!sz)
 			continue;
+
+		if (!mapfn)
+			continue;
+
 		err = mapfn(phdr.p_vaddr, sz, phdr.p_offset, data);
 		if (err)
 			return err;
-- 
1.8.5.2

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web