Commit Graph

135 Commits

Author SHA1 Message Date
Kui-Feng Lee 724c8fddd7 dwarf_loader: Receive per-thread data on worker threads
Add arguments to steal and thread_exit callbacks of conf_load to
receive per-thread data.

Signed-off-by: Kui-Feng Lee <kuifeng@fb.com>
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: bpf@vger.kernel.org
Cc: dwarves@vger.kernel.org
Link: https://lore.kernel.org/r/20220126192039.2840752-2-kuifeng@fb.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2022-01-28 16:19:29 -03:00
Douglas Raillard 772725a77d dwarves_fprintf: Move cacheline_size into struct conf_fprintf
Remove the global variable and turn it into a member in struct
conf_fprintf, so that it can be used by other parts of the code.

Signed-off-by: Douglas Raillard <douglas.raillard@arm.com>
Cc: dwarves@vger.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-10-28 10:17:59 -03:00
Arnaldo Carvalho de Melo 24404190b8 elf_symtab: Remove needless GElf_Ehdr pointer argument from the constructor
We don't need it as we used it only for calling elf_section_by_name(),
that doesn't need it anymore.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-08-20 16:40:27 -03:00
Arnaldo Carvalho de Melo 9d0e3ab9a2 pahole: function__name() doesn't need a 'struct cu *' argument
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-08-12 09:39:46 -03:00
Arnaldo Carvalho de Melo c127d25daf core: class__name() doesn't need a cu arg
Now that namespace->name is a real char string.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-08-12 09:39:46 -03:00
Arnaldo Carvalho de Melo 00e8c5fe21 core: type__name() doesn't need a cu arg
Now that namespace->name is a real char string.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-08-12 09:39:46 -03:00
Arnaldo Carvalho de Melo 790dfbda79 headers: Rebame __unused to __maybe_unused to avoid clashes with system headers
Andrii reported that __unused is a field in /usr/include/bits/stat.h and
vmlinux.h (generated by bpftool), so use the Linux kernel jargon for
this and rename it to '__maybe_unused'.

Reported-by: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-13 10:25:35 -03:00
Arnaldo Carvalho de Melo 25753e0396 pfunct: Use load stealer to speed up --class
We were loading everything to then iterate looking for functions with
pointers to the --class argument, do it in the stealer and go on
ditching the already processed data, greatly speeding up the process.

  $ pfunct -c perf_event_attr
  security_perf_event_open
  register_user_hw_breakpoint
  modify_user_hw_breakpoint
  perf_event_create_kernel_counter
  register_wide_hw_breakpoint
  bpf_lsm_perf_event_open
  modify_user_hw_breakpoint_check
  perf_event_create_kernel_counter
  $
  $
  $ pfunct bpf_lsm_perf_event_open
  int bpf_lsm_perf_event_open(struct perf_event_attr * attr, int type);
  $

  $ for function in `pfunct -c perf_event_attr` ; do pfunct $function ; done
  int security_perf_event_open(struct perf_event_attr * attr, int type);
  struct perf_event * register_user_hw_breakpoint(struct perf_event_attr * attr, perf_overflow_handler_t triggered, void * context, struct task_struct * tsk);
  int modify_user_hw_breakpoint(struct perf_event * bp, struct perf_event_attr * attr);
  struct perf_event * perf_event_create_kernel_counter(struct perf_event_attr * attr, int cpu, struct task_struct * task, perf_overflow_handler_t callback, void * context);
  struct perf_event * * register_wide_hw_breakpoint(struct perf_event_attr * attr, perf_overflow_handler_t triggered, void * context);
  int bpf_lsm_perf_event_open(struct perf_event_attr * attr, int type);
  int modify_user_hw_breakpoint_check(struct perf_event * bp, struct perf_event_attr * attr, bool check);
  struct perf_event * perf_event_create_kernel_counter(struct perf_event_attr * attr, int cpu, struct task_struct * task, perf_overflow_handler_t callback, void * context);
  $

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2020-11-16 08:15:23 -03:00
Arnaldo Carvalho de Melo 9fa3a100f7 pfunct: Use a load stealer to stop as soon as a function is found
When --function/-f or just using the function name as the sole arg,
greatly speeding up the process.

Example using /sys/kernel/btf/vmlinux:

Before:

  $ perf stat -r5 pfunct tcp_v4_rcv
  int tcp_v4_rcv(struct sk_buff * skb);
  int tcp_v4_rcv(struct sk_buff * skb);
  int tcp_v4_rcv(struct sk_buff * skb);
  int tcp_v4_rcv(struct sk_buff * skb);
  int tcp_v4_rcv(struct sk_buff * skb);

   Performance counter stats for 'pfunct tcp_v4_rcv' (5 runs):

           13,199.77 msec task-clock:u              #    1.000 CPUs utilized            ( +-  0.27% )
                   0      context-switches:u        #    0.000 K/sec
                   0      cpu-migrations:u          #    0.000 K/sec
               9,426      page-faults:u             #    0.714 K/sec                    ( +-  0.02% )
      57,793,399,298      cycles:u                  #    4.378 GHz                      ( +-  0.29% )  (83.33%)
         305,498,117      stalled-cycles-frontend:u #    0.53% frontend cycles idle     ( +-  2.87% )  (83.33%)
      15,537,903,799      stalled-cycles-backend:u  #   26.89% backend cycles idle      ( +-  4.04% )  (83.33%)
     126,344,414,608      instructions:u            #    2.19  insn per cycle
                                                    #    0.12  stalled cycles per insn  ( +-  0.00% )  (83.33%)
      26,880,839,847      branches:u                # 2036.463 M/sec                    ( +-  0.01% )  (83.34%)
         122,011,679      branch-misses:u           #    0.45% of all branches          ( +-  0.13% )  (83.33%)

             13.2005 +- 0.0355 seconds time elapsed  ( +-  0.27% )

  $

After:

  $ perf stat -r5 pfunct tcp_v4_rcv
  int tcp_v4_rcv(struct sk_buff * skb);
  int tcp_v4_rcv(struct sk_buff * skb);
  int tcp_v4_rcv(struct sk_buff * skb);
  int tcp_v4_rcv(struct sk_buff * skb);
  int tcp_v4_rcv(struct sk_buff * skb);

   Performance counter stats for 'pfunct tcp_v4_rcv' (5 runs):

               41.89 msec task-clock:u              #    0.993 CPUs utilized            ( +- 11.34% )
                   0      context-switches:u        #    0.000 K/sec
                   0      cpu-migrations:u          #    0.000 K/sec
               9,424      page-faults:u             #    0.225 M/sec                    ( +-  0.01% )
         117,923,321      cycles:u                  #    2.815 GHz                      ( +-  2.13% )  (82.15%)
           1,014,685      stalled-cycles-frontend:u #    0.86% frontend cycles idle     ( +-  5.81% )  (83.48%)
          37,728,636      stalled-cycles-backend:u  #   31.99% backend cycles idle      ( +-  4.77% )  (83.80%)
         215,262,313      instructions:u            #    1.83  insn per cycle
                                                    #    0.18  stalled cycles per insn  ( +-  0.96% )  (83.77%)
          36,786,262      branches:u                #  878.162 M/sec                    ( +-  0.46% )  (83.80%)
             338,322      branch-misses:u           #    0.92% of all branches          ( +-  2.10% )  (83.01%)

             0.04220 +- 0.00478 seconds time elapsed  ( +- 11.33% )

  $

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2020-11-10 15:47:17 -03:00
Arnaldo Carvalho de Melo de18bd5fe3 pfunct: Try sole argument as a function name, just like pahole
I.e.:

This:

  $ pfunct -f tcp_v4_rcv
  int tcp_v4_rcv(struct sk_buff * skb);
  $

Now is equivalent to:

  $ pfunct tcp_v4_rcv
  int tcp_v4_rcv(struct sk_buff * skb);
  $

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2020-11-10 14:57:35 -03:00
Arnaldo Carvalho de Melo ccf3eebfcd btf_loader: Add support for BTF_KIND_FUNC
Some changes to the fprintf routines were needed, as BTF has as the
function type just a BTF_KIND_FUNC_PROTO, while DWARF has as the type
for a function its return value type. With a function->btf flag this was
overcome and all the other goodies in pfunct are present, for instance:

  $ pahole -JV examples/tcp.o | grep -w FUNC | head
  [4068] FUNC tcp_init type_id=4067
  [4070] FUNC tcp_abort type_id=4069
  [4072] FUNC tcp_done type_id=4071
  [4074] FUNC tcp_md5_hash_key type_id=4073
  [4076] FUNC tcp_md5_hash_skb_data type_id=4075
  [4078] FUNC tcp_get_md5sig_pool type_id=4077
  [4080] FUNC tcp_alloc_md5sig_pool type_id=4079
  [4082] FUNC compat_tcp_getsockopt type_id=4081
  [4084] FUNC tcp_getsockopt type_id=4083
  [4086] FUNC tcp_get_timestamping_opt_stats type_id=4085
  $

  $ pfunct -F btf examples/tcp.o  | head
  memset
  memcpy
  tcp_enter_memory_pressure
  tcp_leave_memory_pressure
  tcp_init_sock
  tcp_init_transfer
  tcp_poll
  tcp_ioctl
  tcp_splice_read
  sk_stream_alloc_skb
  $

  $ pfunct --prototype -F btf examples/tcp.o | head
  void * memset(void * p, int c, __kernel_size_t size);
  void * memcpy(void * p, const void  * q, __kernel_size_t size);
  void tcp_enter_memory_pressure(struct sock * sk);
  void tcp_leave_memory_pressure(struct sock * sk);
  void tcp_init_sock(struct sock * sk);
  void tcp_init_transfer(struct sock * sk, int bpf_op);
  __poll_t tcp_poll(struct file * file, struct socket * sock, poll_table * wait);
  int tcp_ioctl(struct sock * sk, int cmd, long unsigned int arg);
  ssize_t tcp_splice_read(struct socket * sock, loff_t * ppos, struct pipe_inode_info * pipe, size_t len, unsigned int flags);
  struct sk_buff * sk_stream_alloc_skb(struct sock * sk, int size, gfp_t gfp, bool force_schedule);
  $

Now to ask just for the 'struct sock' 'methods', i.e. functions that
have as one of its arguments a pointer to the given 'class' name:

  $ pfunct --class sock -F btf examples/tcp.o | head
  tcp_abort
  tcp_done
  compat_tcp_getsockopt
  tcp_getsockopt
  tcp_get_info
  compat_tcp_setsockopt
  tcp_setsockopt
  tcp_disconnect
  tcp_write_queue_purge
  tcp_close
  $

Then ask for the prototypes, which requires -V, should have that fixed:

  $ pfunct -V --prototypes --class sock -F btf examples/tcp.o | head
  int tcp_abort(struct sock * sk, int err);
  void tcp_done(struct sock * sk);
  int compat_tcp_getsockopt(struct sock * sk, int level, int optname, char * optval, int * optlen);
  int tcp_getsockopt(struct sock * sk, int level, int optname, char * optval, int * optlen);
  void tcp_get_info(struct sock * sk, struct tcp_info * info);
  int compat_tcp_setsockopt(struct sock * sk, int level, int optname, char * optval, unsigned int optlen);
  int tcp_setsockopt(struct sock * sk, int level, int optname, char * optval, unsigned int optlen);
  int tcp_disconnect(struct sock * sk, int flags);
  void tcp_write_queue_purge(struct sock * sk);
  void tcp_close(struct sock * sk, long int timeout);
  $

Don't like prototypes with parm names, got you covered:

  $ pfunct --no_parm_names -V --prototypes --class sock -F btf examples/tcp.o | head
  int tcp_abort(struct sock *, int);
  void tcp_done(struct sock *);
  int compat_tcp_getsockopt(struct sock *, int, int, char *, int *);
  int tcp_getsockopt(struct sock *, int, int, char *, int *);
  void tcp_get_info(struct sock *, struct tcp_info *);
  int compat_tcp_setsockopt(struct sock *, int, int, char *, unsigned int);
  int tcp_setsockopt(struct sock *, int, int, char *, unsigned int);
  int tcp_disconnect(struct sock *, int);
  void tcp_write_queue_purge(struct sock *);
  void tcp_close(struct sock *, long int);
  $

Don't like long options and want just one function?

  $ pfunct -f tcp_setsockopt -F btf examples/tcp.o
  int tcp_setsockopt(struct sock * sk, int level, int optname, char * optval, unsigned int optlen);
  $

Want to generate compileable code for all of those functions, full with
the necessary types, etc?

  $ pfunct -F btf --compile examples/tcp.o  > a.c
  $ gcc -c -o a.o a.c
  $ pfunct -F dwarf --prototypes --class sock a.o | head
  pfunct: a.o: No debugging information found
  $ gcc -g -c -o a.o a.c
  $ pfunct -V -F dwarf --prototypes --class sock a.o | head
  void tcp_enter_memory_pressure(struct sock * sk);
  void tcp_leave_memory_pressure(struct sock * sk);
  void tcp_init_sock(struct sock * sk);
  void tcp_init_transfer(struct sock * sk, int bpf_op);
  int tcp_ioctl(struct sock * sk, int cmd, long unsigned int arg);
  struct sk_buff * sk_stream_alloc_skb(struct sock * sk, int size, gfp_t gfp, bool force_schedule);
  ssize_t do_tcp_sendpages(struct sock * sk, struct page * page, int offset, size_t size, int flags);
  int tcp_sendpage_locked(struct sock * sk, struct page * page, int offset, size_t size, int flags);
  int tcp_sendpage(struct sock * sk, struct page * page, int offset, size_t size, int flags);
  int tcp_sendmsg_locked(struct sock * sk, struct msghdr * msg, size_t size);
  $

Now lets go full circle and encode BTF for this a.o generated from
source code generated from the original BTF info in that examples/tcp.o
file:

  $ pahole -JV a.o | tail
  [465] FUNC_PROTO (anon) return=35 args=(392 hp, 393 skb, 5 header_len)
  [466] FUNC tcp_md5_hash_skb_data type_id=465
  [467] FUNC_PROTO (anon) return=35 args=(392 hp, 394 key)
  [468] FUNC tcp_md5_hash_key type_id=467
  [469] FUNC_PROTO (anon) return=0 args=(49 sk)
  [470] FUNC tcp_done type_id=469
  [471] FUNC_PROTO (anon) return=35 args=(49 sk, 35 err)
  [472] FUNC tcp_abort type_id=471
  [473] FUNC_PROTO (anon) return=0 args=(void)
  [474] FUNC tcp_init type_id=473
  $

  $ pfunct -F btf -V --prototypes --class=sock a.o | head
  void tcp_enter_memory_pressure(struct sock * sk);
  void tcp_leave_memory_pressure(struct sock * sk);
  void tcp_init_sock(struct sock * sk);
  void tcp_init_transfer(struct sock * sk, int bpf_op);
  int tcp_ioctl(struct sock * sk, int cmd, long unsigned int arg);
  struct sk_buff * sk_stream_alloc_skb(struct sock * sk, int size, gfp_t gfp, bool force_schedule);
  ssize_t do_tcp_sendpages(struct sock * sk, struct page * page, int offset, size_t size, int flags);
  int tcp_sendpage_locked(struct sock * sk, struct page * page, int offset, size_t size, int flags);
  int tcp_sendpage(struct sock * sk, struct page * page, int offset, size_t size, int flags);
  int tcp_sendmsg_locked(struct sock * sk, struct msghdr * msg, size_t size);
  $

Curious about the code generated by 'pfunct -F btf --compile examples/tcp.o?

  http://vger.kernel.org/~acme/pahole/pfunct-F-BTF--compile-examples-tcp.o.txt

Cc: Alexei Starovoitov <ast@fb.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Cc: Andrii Nakryiko <andriin@fb.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Yonghong Song <yhs@fb.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-11-05 12:04:23 -03:00
Arnaldo Carvalho de Melo f95fd85f7b pfunct: type->type == 0 is void, fix --compile for that
We were using the fall back for that, i.e. 'return 0;' was being emitted
for a function returning void, noticed with using BTF as the format.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-11-05 12:04:17 -03:00
Arnaldo Carvalho de Melo 0fb727166a pfunct: Strip inlines in the code generated for --compile
If we have:

inline void process_adjtimex_modes(const struct __kernel_timex  * txc, s32 * time_tai)
{
}

And any other struct receiving as a parameter pointers to 'struct
__kerne_timex', then the source file with the above inline, since it
doesn't have any inline expansion, i.e. 'pfunct --compile' generates
just empty function bodies, the types won't be included in the resulting
.o.

Since the original file has the expansions, type types will be there and
thus we will not be able to compare those types, so ask for any 'inline'
to be stripped, so that we keep those types and 'fullcircle' can do its
work.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-04-16 15:00:44 -03:00
Arnaldo Carvalho de Melo 09ed2e78be pfunct: Emit definitions for pointers inside pointer to function args
When using --compile we were missing emitting the types for function
arguments in function pointers arguments, i.e.:

Before:

  /home/acme/git/build/v5.1-rc4+/kernel/events/core.o
  /tmp/fullcircle.CZeLch.c:3770:141: warning: ‘struct perf_output_handle’ declared inside parameter list will not be visible outside of this definition or declaration
   inline int __perf_event_output(struct perf_event * event, struct perf_sample_data * data, struct pt_regs * regs, int (*output_begin)(struct perf_output_handle *, struct perf_event *, unsigned int))
                                                                                                                                               ^~~~~~~~~~~~~~~~~~

After:

  $ pfunct --compile /home/acme/git/build/v5.1-rc4+/kernel/events/core.o > a.c
  $ gcc -g -c a.c
  $ grep -w perf_output_handle -m1 -A5 a.c
  struct perf_output_handle;

  inline int __perf_event_output(struct perf_event * event, struct perf_sample_data * data, struct pt_regs * regs, int (*output_begin)(struct perf_output_handle *, struct perf_event *, unsigned int))
  {
	  return 0;
  }
  $

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-04-16 14:05:01 -03:00
Arnaldo Carvalho de Melo c7fd9cc1fe pfunct: Fixup more return types
Covering typedefs, unions.

Fixes: 99750f244c ("pfunct: Generate a valid return type for the --compile bodies")
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-04-15 20:53:50 -03:00
Arnaldo Carvalho de Melo 49c27bdd66 core: Allow the loaders to advertise features they have
For instance, DWARF has DW_AT_alignment, and some output features
require that, so let loaders advertise such things, next patch will use
this info.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-04-15 14:45:27 -03:00
Arnaldo Carvalho de Melo 99750f244c pfunct: Generate a valid return type for the --compile bodies
Before:

  $ pfunct --compile examples/tcp.o > tcp.pahole.c
  $ clang --target=bpf -c -g tcp.pahole.c |& tail
  tcp.pahole.c:6154:1: warning: control reaches end of non-void function [-Wreturn-type]
  }
  ^
  tcp.pahole.c:6158:1: warning: control reaches end of non-void function [-Wreturn-type]
  }
  ^
  tcp.pahole.c:6170:1: warning: control reaches end of non-void function [-Wreturn-type]
  }
  ^
  192 warnings generated.
  $ head -6170 tcp.pahole.c | tail -3
  inline int arch_atomic_read(const atomic_t  * v)
  {
  }
  $

After:

  $ pfunct --compile examples/tcp.o > tcp.pahole.c
  $ clang --target=bpf -c -g tcp.pahole.c
  $ grep -A3 -w arch_atomic_read tcp.pahole.c
  inline int arch_atomic_read(const atomic_t  * v)
  {
	  return 0;
  }
  $

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-04-05 16:33:43 -03:00
Arnaldo Carvalho de Melo 45ad545944 tag: Introduce tag__is_pointer()
For the usual idiom to ask if a tag is a pointer, removing a bit of
DWARFism and shortening the operation.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-04-05 15:21:55 -03:00
Arnaldo Carvalho de Melo 7aec7dd6c2 pfunct: Do not reconstruct external functions
I.e. those with DW_AT_external set, to avoid regenerating multiple times
things like __compiletime_assert_1504:

 <5><2fc41>: Abbrev Number: 100 (DW_TAG_subprogram)
    <2fc42>   DW_AT_external    : 1
    <2fc42>   DW_AT_name        : (indirect string, offset: 0x1751f): __compiletime_assert_1504
    <2fc46>   DW_AT_decl_file   : 1
    <2fc47>   DW_AT_decl_line   : 1504
    <2fc49>   DW_AT_decl_column : 2
    <2fc4a>   DW_AT_prototyped  : 1
    <2fc4a>   DW_AT_declaration : 1
 <5><2fc4a>: Abbrev Number: 0
 <4><2fc4b>: Abbrev Number: 0
 <3><2fc4c>: Abbrev Number: 0
 <2><2fc4d>: Abbrev Number: 34 (DW_TAG_lexical_block)
 <3><2fc4e>: Abbrev Number: 12 (DW_TAG_variable)
    <2fc4f>   DW_AT_name        : (indirect string, offset: 0xbcc6): ____ptr
    <2fc53>   DW_AT_decl_file   : 1
    <2fc54>   DW_AT_decl_line   : 1504
    <2fc56>   DW_AT_decl_column : 2
    <2fc57>   DW_AT_type        : <0x6441>
 <3><2fc5b>: Abbrev Number: 34 (DW_TAG_lexical_block)
 <4><2fc5c>: Abbrev Number: 12 (DW_TAG_variable)
    <2fc5d>   DW_AT_name        : (indirect string, offset: 0xeb74): __mptr
    <2fc61>   DW_AT_decl_file   : 1
    <2fc62>   DW_AT_decl_line   : 1504
    <2fc64>   DW_AT_decl_column : 2
    <2fc65>   DW_AT_type        : <0x5a2>
 <4><2fc69>: Abbrev Number: 34 (DW_TAG_lexical_block)
 <5><2fc6a>: Abbrev Number: 100 (DW_TAG_subprogram)
    <2fc6b>   DW_AT_external    : 1
    <2fc6b>   DW_AT_name        : (indirect string, offset: 0x1751f): __compiletime_assert_1504
    <2fc6f>   DW_AT_decl_file   : 1
    <2fc70>   DW_AT_decl_line   : 1504
    <2fc72>   DW_AT_decl_column : 2
    <2fc73>   DW_AT_prototyped  : 1
    <2fc73>   DW_AT_declaration : 1

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-04-04 21:59:23 -03:00
Arnaldo Carvalho de Melo 163b873f81 pfunct: Do not reconstruct inline expansions of functions
I.e. those that point back to the inline function via
DW_AT_abstract_origin.

For instance:

 <1><34b65>: Abbrev Number: 156 (DW_TAG_subprogram)
    <34b67>   DW_AT_external    : 1
    <34b67>   DW_AT_name        : (indirect string, offset: 0x2404): tcp_enter_memory_pressure
    <34b6b>   DW_AT_decl_file   : 1
    <34b6c>   DW_AT_decl_line   : 324
    <34b6e>   DW_AT_decl_column : 6
    <34b6f>   DW_AT_prototyped  : 1
    <34b6f>   DW_AT_inline      : 1     (inlined)

  <SNIP>

   <1><37f45>: Abbrev Number: 149 (DW_TAG_subprogram)
    <37f47>   DW_AT_abstract_origin: <0x34b65>
    <37f4b>   DW_AT_low_pc      : 0x1000
    <37f53>   DW_AT_high_pc     : 0x48
    <37f5b>   DW_AT_frame_base  : 1 byte block: 9c      (DW_OP_call_frame_cfa)
    <37f5d>   DW_AT_GNU_all_call_sites: 1
    <37f5d>   DW_AT_sibling     : <0x38032>

Generated by:

  Compilation Unit @ offset 0x0:
   Length:        0x3b40b (32-bit)
   Version:       4
   Abbrev Offset: 0x0
   Pointer Size:  8
 <0><b>: Abbrev Number: 215 (DW_TAG_compile_unit)
    <d>   DW_AT_producer    : (indirect string, offset: 0xb0bc): GNU C89 8.2.1 20181215 (Red Hat 8.2.1-6) -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -mindirect-branch=thunk-extern -mindirect-branch-register -mrecord-mcount -mfentry -march=x86-64 -g -O2 -std=gnu90 -p -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE -falign-jumps=1 -falign-loops=1 -fno-asynchronous-unwind-tables -fno-delete-null-pointer-checks -fstack-protector-strong -fno-var-tracking-assignments -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fstack-check=no -fconserve-stack --param allow-store-data-races=0
    <11>   DW_AT_language    : 1        (ANSI C)
    <12>   DW_AT_name        : (indirect string, offset: 0x10daa): /home/acme/git/linux/net/ipv4/tcp.c
    <16>   DW_AT_comp_dir    : (indirect string, offset: 0x1d8c5): /home/acme/git/build/v5.0+

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-04-04 21:59:23 -03:00
Arnaldo Carvalho de Melo ea83b780ec pfunct: Handle unnamed struct typedefs
If we first reconstruct all the types needed for a typedef to then
reconstruct it, we may end up with the unnamed struct correctly
reconstructed and then this:

  tcp.pahole.c:1987:17: warning: useless storage class specifier in empty declaration
   typedef struct  read_descriptor_t;

I.e.:

  typedef struct {
          size_t                     written;              /*     0     8 */
          size_t                     count;                /*     8     8 */
          union {
                  char *             buf;                  /*    16     8 */
                  void *             data;                 /*    16     8 */
          } arg;                                           /*    16     8 */
          int                        error;                /*    24     4 */

          /* size: 32, cachelines: 1, members: 4 */
          /* padding: 4 */
          /* last cacheline: 32 bytes */
  } read_descriptor_t;
  typedef struct  read_descriptor_t;

So special case it.

XXX

I'll revisit this, looks suboptimal, we manage to get this right
when reconstructing nameless struct typedefs found as the types for
members of structs or unions...

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-04-04 21:59:23 -03:00
Arnaldo Carvalho de Melo 093135b0bf pfunct: Do not emit a type multiple times
We need to check if tag__type(type)->definition_emitted is set before
asking for that type to be emitted, otherwise we get type redefinition
errors when trying to compile the output from pahole --expand_types.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-04-04 21:59:23 -03:00
Arnaldo Carvalho de Melo 3ce2c52166 pfunct: Ask for generating compilable output that generates DWARF for types
I.e. --compile is similar to --expand_types but also makes sure the
function have empty function bodies, which ends up making at least gcc
to generate the DWARF info for the types referenced by the function
arguments and return types.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-04-04 21:59:23 -03:00
Arnaldo Carvalho de Melo e7a786540d pfunct: Make --expand_types/-b without -f expand types for all functions
Previously we wouldn't expand types if the user didn't provide a
function name, make it expand the types for all function arguments if
no function name is provided.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-04-04 21:59:20 -03:00
Arnaldo Carvalho de Melo 9b2eadf97b pfunct: Follow const, restrict, volatile in --expand_types
Take:

  int tcp_md5_hash_key(struct tcp_md5sig_pool *hp, const struct tcp_md5sig_key *key)

We were not generating the 'struct tcp_md5sig_key' forward decl or
struct definition, stopping at 'const', which made this uncompilable.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-04-04 15:45:26 -03:00
Arnaldo Carvalho de Melo f3f86f2f89 pfunct: Reconstruct function return types for --expand_types
Not just for the function arguments, so that we are able to get
something closer to buildable.

So far we got it buildable when the return types were reconstructed
because they also appeared in one of the function arguments or
in structs used by them.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-04-04 15:39:26 -03:00
Arnaldo Carvalho de Melo 5375d06faf dwarves: Introduce type_id_t for use with the type IDs
This is just a prep patch, marking uint16_t IDs as type_id_t, that
points to uint16_t, so no change in the resulting code.

Cc: Andrii Nakryiko <andriin@fb.com>
Tested-by:Andrii Nakryiko <andrii.nakryiko@gmail.com>
Link: https://lore.kernel.org/bpf/CAEf4Bzb0SpvXdDKMMnUof==kp4Y0AP54bKFjeCzX_AsmDm7k7g@mail.gmail.com/
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-03-11 11:44:53 -03:00
Domenico Andreoli e714d2eaa1 Adopt SPDX-License-Identifier
Signed-off-by: Domenico Andreoli <domenico.andreoli@linux.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-01-18 15:41:48 -03:00
Arnaldo Carvalho de Melo 02a456f5f5 pahole: Search and use running kernel vmlinux when no file is passed
Seems like a nice shortcut for kernel hackers, and one that makes sure
the right vmlinux file is used, as it reads the running kernel build id
from /sys/kernel/notes and then searches the well known path for vmlinux
files:

vmlinux
/boot/vmlinux
/boot/vmlinux-4.14.0+
/usr/lib/debug/boot/vmlinux-`uname -r`
/lib/modules/`uname -r`/build/vmlinux
/usr/lib/debug/lib/modules/`uname -r`/vmlinux
/usr/lib/debug/boot/vmlinux-`uname -r`.debug

To find one with a matching build id (.notes ELF section, then
nhdr->n_type == NT_GNU_BUILD_ID), just like the Linux kernel 'perf
tools', where this code comes from, with some minor modifications to
cope with not having symbol_conf, symfs, etc.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2017-11-24 11:24:16 -03:00
Arnaldo Carvalho de Melo 8af5ccd86d dwarves: Use cus__fprintf_load_files_err() in the remaining tools
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-03-15 14:29:57 -03:00
Arnaldo Carvalho de Melo a54515fa6e dwarves: Stop using 'self'
As Thomas Gleixner wisely pointed out, using 'self' is stupid, it
doesn't convey useful information, so use sensible names.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2012-08-17 18:47:15 -03:00
Arnaldo Carvalho de Melo c0bdd19f0e pfunct: Introduce '-P'/'--prototypes'
To print all the function prototypes.

Based-on-patch-by: Rakesh Pandit <rakesh.pandit@gmail.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2010-05-04 13:33:08 -03:00
Arnaldo Carvalho de Melo 9c0cb4939c dwarves: Allow avoiding loading addr information
As, for instance, pahole doesn't need it at all.

Down from:

[acme@doppio pahole]$ perf stat -r 5 pahole object_samples/zweinberg\@mozilla.com/libgklayout.so > /dev/null

 Performance counter stats for 'pahole object_samples/zweinberg@mozilla.com/libgklayout.so' (5 runs):

   17233.989563  task-clock-msecs         #      0.994 CPUs    ( +-   0.076% )
           1880  context-switches         #      0.000 M/sec   ( +-   0.159% )
              0  CPU-migrations           #      0.000 M/sec   ( +-   0.000% )
          26248  page-faults              #      0.002 M/sec   ( +-   0.000% )
    34244461105  cycles                   #   1987.030 M/sec   ( +-   0.078% )
    34510583834  instructions             #      1.008 IPC     ( +-   0.001% )
      445937867  cache-references         #     25.875 M/sec   ( +-   0.160% )
       56898165  cache-misses             #      3.302 M/sec   ( +-   0.074% )

   17.335292038  seconds time elapsed   ( +-   0.076% )

[acme@doppio pahole]$

To:

[acme@doppio pahole]$ perf stat -r 5 pahole object_samples/zweinberg\@mozilla.com/libgklayout.so > /dev/null

 Performance counter stats for 'pahole object_samples/zweinberg@mozilla.com/libgklayout.so' (5 runs):

   16511.627334  task-clock-msecs         #      0.992 CPUs    ( +-   0.208% )
           1922  context-switches         #      0.000 M/sec   ( +-   3.068% )
              0  CPU-migrations           #      0.000 M/sec   ( +-   0.000% )
          25570  page-faults              #      0.002 M/sec   ( +-   0.000% )
    32807624343  cycles                   #   1986.941 M/sec   ( +-   0.208% )
    32711598374  instructions             #      0.997 IPC     ( +-   0.001% )
      436345377  cache-references         #     26.427 M/sec   ( +-   0.178% )
       54044997  cache-misses             #      3.273 M/sec   ( +-   0.685% )

   16.652951166  seconds time elapsed   ( +-   0.304% )

[acme@doppio pahole]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-07-06 13:44:57 -03:00
Arnaldo Carvalho de Melo e429f8efbb dwarves: Add an rbtree for the functions in a cu
That is used by cus__find_function_by_addr & cu__func_function_by_addr.

First user is pfunct --addr, but this is really for pfunct --annotate, that
will process a perf.data file generated by 'perf report', load the debugging
info and regenerate the functions (pfunct -TVi like) that had hits, using
libdisasm to show the assembly code, etc.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-06-04 14:56:44 -03:00
Arnaldo Carvalho de Melo 73548f6be3 all: Fix possible uninitialized variable uses
I wasn't especifying the optimization level and the default, despite
using -Wall, was for this so simple case not to be warned about, so
now I'm using -O2.

Alexandre provided a patch initializing the variables to NULL, so that
when we called cus__delete it would bail out and not possibly act on
a random value, I preferred to add extra goto labels and do the exit
path only on the resources that were successfully allocated/initialized,
avoiding, for instance, to call dwarves_exit() if dwarves_init() wasn't
called, which wasn't a problem so far, but could be in the future.

Reported-by: Alexandre Vassalotti <alexandre@peadrop.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-05-04 15:50:06 -03:00
Arnaldo Carvalho de Melo 6025d4ce38 pfunct: Stop using cu__for_each_tag
All it really needs its the recently introduced cu__for_each_function.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-04-01 11:55:49 -03:00
Arnaldo Carvalho de Melo 2d8700009b pfunct: Introduce --no_parm_names
Because CTF doesn't encodes the names of the parameters and I want to
test the upcoming CTF function section code in ctftwdiff.

$ pfunct -V pahole > /tmp/before
$ pfunct --no_parm_names -V pahole > /tmp/after
$ diff -u /tmp/before /tmp/after | tail -3
-struct structure * structure__new(strings_t name);
+struct structure * structure__new(strings_t);
 /* definitions: 1 */
$

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-30 21:47:59 -03:00
Arnaldo Carvalho de Melo 31fd625644 elf_symtab: Fix bogus elf_symtab__is_local_function
It should look for functions, not OBJECTS (variables).

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-28 19:27:00 -03:00
Arnaldo Carvalho de Melo 640bfd9679 pfunct: Introduce --symtab
With an optional argument, that if not especified defaults to
".symtab": example:

[acme@emilia pahole]$ pfunct --symtab=".dynsym" pahole
54: strings                   0x606480     8
56: _IO_stdin_used            0x403ec0     4
60: stderr                    0x606488     8
68: argp_program_version_hook 0x404038     8
69: stdout                    0x606490     8
[acme@emilia pahole]$

Yes, some filtering is done

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-25 18:03:28 -03:00
Arnaldo Carvalho de Melo 25264fdf74 pfunct: Add --format_path/-F as in pahole
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-24 16:39:14 -03:00
Arnaldo Carvalho de Melo 140712f06a cu: Rename cu__find_{type,tag}_by_id to cu__{type,tag}
To shorten the name and to reflect the fact that we're no longer
"finding" a type, but merely accessing an array with a bounds check in
this function.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-18 12:17:07 -03:00
Arnaldo Carvalho de Melo 4d44276d85 coding style: remove trailing whitespaces, etc
Amazing how many crept up over time, should have set the
execute bit of .git/hooks/pre-commit already, duh.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-14 13:50:36 -03:00
Arnaldo Carvalho de Melo 991c6a3ebb dwarves: Rename cus__loadfl with cus__load_files
Also introducing cus__load, that load just one file.

The new cus__load_files routine now iterates thru the provided array
calling cus__load for each, and that in turn will try first dwarf__load,
and if that fail, i.e. if no DWARF info is found, call ctf__load.

This now allows loading DWARF _and_ CTF files at the same time. This
will be useful in the future when we, from DWARF generate CTF and at the
same time do a codiff, comparing the freshly generated CTF file with the
DWARF it came from.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-13 10:49:01 -03:00
Arnaldo Carvalho de Melo 8cc4949b00 dwarves: Add destructors
So that at program exit we can verify, using tools, that no memory was
leaked.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-11 12:31:17 -03:00
Arnaldo Carvalho de Melo 250dded466 dwarf: separate dwarf_tag from tag
So that, when not needing the DWARF info, the apps can tell that at load
time, and then the dwarf loader can just free all the dwarf_tags
allocated, reducing memory usage.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-09 14:43:47 -03:00
Arnaldo Carvalho de Melo 20464ba7f0 dwarves: Reduce the size of some data structures
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-07 16:45:09 -03:00
Arnaldo Carvalho de Melo 9fadbfffba dwarves: use tag__is_function in the tools
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-06 11:14:26 -03:00
Arnaldo Carvalho de Melo a2289d0606 dwarves: Ditch parameter__type and simplify parameter__name
parameter__type was needed because the abstract_origin resolution was
done later, now it is at dwarf recode time, and for debugging formats
that don't have this crap, never. So it now can use the same idiom as
other tags: foo->tag.type.

parameter__name still exists because the tools still want a string
returned, but for some what they want is indeed the string_t, so that
when looking for a particular string it can be done as an string__find
for the key + integer comparision instead of doing a costlier strcmp.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-06 09:27:40 -03:00
Arnaldo Carvalho de Melo c178f4698d dwarves: Remove some more DWARF details from the core
Had to be a big sweeping change, but the regression tests shows just
improvements :-)

Now we stop using an id in struct tag, only storing the type, that now
uses 16 bits only, as CTF does.

Each format loader has to go on adding the types to the core, that
figures out if it is a tag that can be on the tag->type field
(tag__is_tag_type).

Formats that already have the types separated and in sequence, such as
CTF, just ask the core to insert in the types_table directly with its
original ID.

For DWARF, we ask the core to put it on the table, in sequence, and return the
index, that is then stashed with the DWARF specific info (original id, type,
decl_line, etc) and hashed by the original id. Later we recode everything,
looking up via the original type, getting the small_id to put on the tag->type.

The underlying debugging info not needed by the core is stashed in tag->priv,
and the DWARF loader now just allocates sizeof(struct dwarf_tag) at the end of
the core tag and points it there, and makes that info available thru
cu->orig_info. In the future we can ask, when loading a cu, that this info be
trown away, so that we reduce the memory footprint for big multi-cu files such
as the Linux kernel.

There is also a routine to ask for inserting a NULL, as we still have
bugs in the CTF decoding and thus some entries are being lost, to avoid
using an undefined pointer when traversing the types_table the ctf
loader puts a NULL there via cu__table_nullify_type_entry() and then
cu__for_each_type skips those.

There is some more cleanups for leftovers that I avoided cleaning to
reduce this changeset.

And also while doing this I saw that enums can appear without any
enumerators and that an array with DW_TAG_GNU_vector is actually a
different tag, encoded this way till we get to DWARF4 ;-)

So now we don't have to lookup on a hash table looking for DWARF
offsets, we can do the more sensible thing of just indexing the
types_tags array.

Now to do some cleanups and try to get the per cu encoder done. Then
order all the cus per number of type entries, pick the one with more,
then go on merging/recoding the types of the others and putting the
parent linkage in place.

Just to show the extent of the changes:

$ codiff /tmp/libdwarves.so.1.0.0 build/libdwarves.so.1.0.0
/home/acme/git/pahole/dwarves.c:
  struct cu                                      | -4048
  struct tag                                     |  -32
  struct ptr_to_member_type                      |  -32
  struct namespace                               |  -32
  struct type                                    |  -32
  struct class                                   |  -32
  struct base_type                               |  -32
  struct array_type                              |  -32
  struct class_member                            |  -32
  struct lexblock                                |  -32
  struct ftype                                   |  -32
  struct function                                |  -64
  struct parameter                               |  -32
  struct variable                                |  -32
  struct inline_expansion                        |  -32
  struct label                                   |  -32
  struct enumerator                              |  -32
 17 structs changed
  tag__follow_typedef                            |   +3
  tag__fprintf_decl_info                         |  +25
  array_type__fprintf                            |   +6
  type__name                                     | -126
  type__find_first_biggest_size_base_type_member |   -3
  typedef__fprintf                               |  +16
  imported_declaration__fprintf                  |   +6
  imported_module__fprintf                       |   +3
  cu__new                                        |  +26
  cu__delete                                     |  +26
  hashtags__hash                                 |  -65
  hash_64                                        | -124
  hlist_add_head                                 |  -78
  hashtags__find                                 | -157
  cu__hash                                       |  -80
  cu__add_tag                                    |  +20
  tag__prefix                                    |   -3
  cu__find_tag_by_id                             |   -2
  cu__find_type_by_id                            |   -3
  cu__find_first_typedef_of_type                 |  +38
  cu__find_base_type_by_name                     |  +68
  cu__find_base_type_by_name_and_size            |  +72
  cu__find_struct_by_name                        |  +59
  cus__find_struct_by_name                       |   +8
  cus__find_tag_by_id                            |   +5
  cus__find_cu_by_name                           |   -6
  lexblock__find_tag_by_id                       | -173
  cu__find_variable_by_id                        | -197
  list__find_tag_by_id                           | -308
  cu__find_parameter_by_id                       |  -60
  tag__ptr_name                                  |   +6
  tag__name                                      |  +15
  variable__type                                 |  +13
  variable__name                                 |   +7
  class_member__size                             |   +6
  parameter__name                                | -119
  tag__parameter                                 |  -14
  parameter__type                                | -143
  type__fprintf                                  |  -29
  union__fprintf                                 |   +6
  class__add_vtable_entry                        |   -9
  type__add_member                               |   -6
  type__clone_members                            |   -3
  enumeration__add                               |   -6
  function__name                                 | -156
  ftype__has_parm_of_type                        |  -39
  class__find_holes                              |  -27
  class__has_hole_ge                             |   -3
  type__nr_members_of_type                       |   +3
  lexblock__account_inline_expansions            |   +3
  cu__account_inline_expansions                  |  -18
  ftype__fprintf_parms                           |  +46
  function__tag_fprintf                          |  +24
  lexblock__fprintf                              |   -6
  ftype__fprintf                                 |   +3
  function__fprintf_stats                        |  -18
  function__size                                 |   -6
  class__vtable_fprintf                          |  -11
  class__fprintf                                 |  -21
  tag__fprintf                                   |  -35
 60 functions changed, 513 bytes added, 2054 bytes removed, diff: -1541

/home/acme/git/pahole/ctf_loader.c:
  struct ctf_short_type      |   +0
 14 structs changed
  type__init                 |  -14
  type__new                  |   -9
  class__new                 |  -12
  create_new_base_type       |   -7
  create_new_base_type_float |   -7
  create_new_array           |   -8
  create_new_subroutine_type |   -9
  create_full_members        |  -18
  create_short_members       |  -18
  create_new_class           |   +1
  create_new_union           |   +1
  create_new_enumeration     |  -19
  create_new_forward_decl    |   -2
  create_new_typedef         |   +3
  create_new_tag             |   -5
  load_types                 |  +16
  class__fixup_ctf_bitfields |   -3
 17 functions changed, 21 bytes added, 131 bytes removed, diff: -110

/home/acme/git/pahole/dwarf_loader.c:
 17 structs changed
  zalloc                           |  -56
  tag__init                        |   +3
  array_type__new                  |  +20
  type__init                       |  -24
  class_member__new                |  +46
  inline_expansion__new            |  +12
  class__new                       |  +81
  lexblock__init                   |  +19
  function__new                    |  +43
  die__create_new_array            |  +20
  die__create_new_parameter        |   +4
  die__create_new_label            |   +4
  die__create_new_subroutine_type  | +113
  die__create_new_enumeration      |  -21
  die__process_class               |  +79
  die__process_namespace           |  +76
  die__create_new_inline_expansion |   +4
  die__process_function            | +147
  __die__process_tag               |  +34
  die__process_unit                |  +56
  die__process                     |  +90
 21 functions changed, 851 bytes added, 101 bytes removed, diff: +750

/home/acme/git/pahole/dwarves.c:
  struct ptr_table             |  +16
  struct cu_orig_info          |  +32
 2 structs changed
  tag__decl_line               |  +68
  tag__decl_file               |  +70
  tag__orig_id                 |  +71
  ptr_table__init              |  +46
  ptr_table__exit              |  +37
  ptr_table__add               | +183
  ptr_table__add_with_id       | +165
  ptr_table__entry             |  +64
  cu__table_add_tag            | +171
  cu__table_nullify_type_entry |  +38
 10 functions changed, 913 bytes added, diff: +913

/home/acme/git/pahole/ctf_loader.c:
 2 structs changed
  tag__alloc          |  +52
 1 function changed, 52 bytes added, diff: +52

/home/acme/git/pahole/dwarf_loader.c:
  struct dwarf_tag                       |  +48
  struct dwarf_cu                        | +4104
 4 structs changed
  dwarf_cu__init                         |  +83
  hashtags__hash                         |  +61
  hash_64                                | +124
  hlist_add_head                         |  +78
  hashtags__find                         | +161
  cu__hash                               |  +95
  tag__is_tag_type                       | +171
  tag__is_type                           |  +85
  tag__is_union                          |  +28
  tag__is_struct                         |  +57
  tag__is_typedef                        |  +28
  tag__is_enumeration                    |  +28
  dwarf_cu__find_tag_by_id               |  +56
  dwarf_cu__find_type_by_id              |  +63
  tag__alloc                             | +114
  __tag__print_type_not_found            | +108
  namespace__recode_dwarf_types          | +346
  tag__namespace                         |  +14
  tag__has_namespace                     |  +86
  tag__is_namespace                      |  +28
  type__recode_dwarf_specification       | +182
  tag__type                              |  +14
  __tag__print_abstract_origin_not_found | +105
  ftype__recode_dwarf_types              | +322
  tag__ftype                             |  +14
  tag__parameter                         |  +14
  lexblock__recode_dwarf_types           | +736
  tag__lexblock                          |  +14
  tag__label                             |  +14
  tag__recode_dwarf_type                 | +766
  tag__ptr_to_member_type                |  +14
  cu__recode_dwarf_types_table           |  +88
  cu__recode_dwarf_types                 |  +48
  dwarf_tag__decl_file                   |  +77
  strings__ptr                           |  +33
  dwarf_tag__decl_line                   |  +59
  dwarf_tag__orig_id                     |  +59
  dwarf_tag__orig_type                   |  +59
 38 functions changed, 4432 bytes added, diff: +4432

build/libdwarves.so.1.0.0:
 147 functions changed, 6782 bytes added, 2286 bytes removed, diff: +4496

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-05 20:40:54 -03:00
Arnaldo Carvalho de Melo 3f4e4457e2 dwarves: Add DW_TAG_ptr_to_member_type to tag__is_tag_type
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-03 15:12:29 -03:00