• Wang Nan's avatar
    perf symbols: Adjust symbol for shared objects · 99e87f7b
    Wang Nan authored
    He Kuang reported a problem that perf fails to get correct symbol on
    Android platform in [1]. The problem can be reproduced on normal x86_64
    platform. I will describe the reproducing steps in detail at the end of
    commit message.
    
    The reason of this problem is the missing of symbol adjustment for normal
    shared objects. In most of the cases skipping adjustment is okay. However,
    when '.text' section have different 'address' and 'offset' the result is wrong.
    I checked all shared objects in my working platform, only wine dll objects and
    debug objects (in .debug) have this problem. However, it is common on Android.
    For example:
    
     $ readelf -S ./libsurfaceflinger.so | grep \.text
       [10] .text             PROGBITS         0000000000029030  00012030
    
    This patch enables symbol adjustment for dynamic objects so the symbol
    address got from elfutils would be adjusted correctly.
    
    Now nearly all types of ELF files should adjust symbols. Makes
    ss->adjust_symbols default to true.
    
    Steps to reproduce the problem:
    
      $ cat ./Makefile
      PWD := $(shell pwd)
      LDFLAGS += "-Wl,-rpath=$(PWD)"
      CFLAGS += -g
      main: main.c libbuggy.so
      libbuggy.so: buggy.c
    	gcc -g -shared -fPIC -Wl,-Ttext-segment=0x200000 $< -o $@
      clean:
    	rm -rf main libbuggy.so *.o
    
      $ cat ./buggy.c
      int fib(int x)
      {
          return (x == 0) ? 1 : (x == 1) ? 1 : fib(x - 1) + fib(x - 2);
      }
    
      $ cat ./main.c
      #include <stdio.h>
    
      extern int fib(int x);
      int main()
      {
         int i;
    
         for (i = 0; i < 40; i++)
             printf("%d\n", fib(i));
         return 0;
     }
    
     $ make
     $ perf record ./main
     ...
     $ perf report --stdio
     # Overhead  Command  Shared Object      Symbol
     # ........  .......  .................  ...............................
     #
         14.97%  main     libbuggy.so        [.] 0x000000000000066c
          8.68%  main     libbuggy.so        [.] 0x00000000000006aa
          8.52%  main     libbuggy.so        [.] fib@plt
          7.95%  main     libbuggy.so        [.] 0x0000000000000664
          5.94%  main     libbuggy.so        [.] 0x00000000000006a9
          5.35%  main     libbuggy.so        [.] 0x0000000000000678
     ...
    
    The correct result should be (after this patch):
    
      # Overhead  Command  Shared Object      Symbol
      # ........  .......  .................  ...............................
      #
          91.47%  main     libbuggy.so        [.] fib
           8.52%  main     libbuggy.so        [.] fib@plt
           0.00%  main     [kernel.kallsyms]  [k] kmem_cache_free
    
    [1] http://lkml.kernel.org/g/1452567507-54013-1-git-send-email-hekuang@huawei.comSigned-off-by: default avatarWang Nan <wangnan0@huawei.com>
    Acked-by: default avatarNamhyung Kim <namhyung@kernel.org>
    Tested-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
    Cc: Adrian Hunter <adrian.hunter@intel.com>
    Cc: Cody P Schafer <dev@codyps.com>
    Cc: He Kuang <hekuang@huawei.com>
    Cc: Jiri Olsa <jolsa@kernel.org>
    Cc: Kirill Smelkov <kirr@nexedi.com>
    Cc: Li Zefan <lizefan@huawei.com>
    Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
    Cc: Zefan Li <lizefan@huawei.com>
    Cc: pi3orama@163.com
    Link: http://lkml.kernel.org/r/1460024671-64774-3-git-send-email-wangnan0@huawei.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
    99e87f7b
symbol-elf.c 40 KB