• Namhyung Kim's avatar
    perf dwarf-aux: Check pointer offset when checking variables · 645af3fb
    Namhyung Kim authored
    In match_var_offset(), it checks the offset range with the target type
    only for non-pointer types.  But it also needs to check the pointer
    types with the target type.
    
    This is because there can be more than one pointer variable located in
    the same register.  Let's look at the following example.  It's looking
    up a variable for reg3 at tcp_get_info+0x62.  It found "sk" variable but
    it wasn't the right one since it accesses beyond the target type (struct
    'sock' in this case) size.
    
      -----------------------------------------------------------
      find data type for 0x7bc(reg3) at tcp_get_info+0x62
      CU for net/ipv4/tcp.c (die:0x7b5f516)
      frame base: cfa=0 fbreg=6
      offset: 1980 is bigger than size: 760
      check variable "sk" failed (die: 0x7b92b2c)
       variable location: reg3
       type='struct sock' size=0x2f8 (die:0x7b63c3ab)
    
    Actually there was another variable "tp" in the function and it's
    located at the same (reg3) because it's just type-casted like below.
    
      void tcp_get_info(struct sock *sk, struct tcp_info *info)
      {
          const struct tcp_sock *tp = tcp_sk(sk);
          ...
    
    The 'struct tcp_sock' contains the 'struct sock' at offset 0 so it can
    just use the same address as a pointer to tcp_sock.  That means it
    should match variables correctly by checking the offset and size.
    Actually it cannot distinguish if the offset was smaller than the size
    of the original struct sock.  But I think it's fine as they are the same
    at that part.
    
    So let's check the target type size and retry if it doesn't match.
    Now it succeeded to find the correct variable.
    
      -----------------------------------------------------------
      find data type for 0x7bc(reg3) at tcp_get_info+0x62
      CU for net/ipv4/tcp.c (die:0x7b5f516)
      frame base: cfa=0 fbreg=6
      found "tp" in scope=1/1 (die: 0x7b92b16) type_offset=0x7bc
       variable location: reg3
       type='struct tcp_sock' size=0xa68 (die:0x7b81380)
    
    Fixes: bc10db8e ("perf annotate-data: Support stack variables")
    Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
    Cc: Adrian Hunter <adrian.hunter@intel.com>
    Cc: Ian Rogers <irogers@google.com>
    Cc: Ingo Molnar <mingo@kernel.org>
    Cc: Jiri Olsa <jolsa@kernel.org>
    Cc: Kan Liang <kan.liang@linux.intel.com>
    Cc: Masami Hiramatsu <mhiramat@kernel.org>
    Cc: Namhyung Kim <namhyung@kernel.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Link: https://lore.kernel.org/r/20240412183310.2518474-3-namhyung@kernel.orgSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
    645af3fb
dwarf-aux.c 51.7 KB