Commit Graph

74 Commits

Author SHA1 Message Date
Arnaldo Carvalho de Melo 95578b7694 [CLASSES]: Shrink struct class_member
[acme@newtoy pahole]$ codiff build/libclasses.so.orig build/libclasses.so
/home/acme/pahole/classes.c:
  struct class_member |  -16
 1 struct changed
  class_member__new   |   +6
  class_member__names |   +5
  class_member__print |   -9
  class__find_holes   |  -37
  class__print_struct |  -22
  cu__process_class   |   +1
 6 functions changed, 12 bytes added, 68 bytes removed
[acme@newtoy pahole]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-28 10:09:18 -02:00
Arnaldo Carvalho de Melo 849eda4a71 [CLASSES]: Fix abstract_origin type, its a Dwarf_Off
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-28 09:38:40 -02:00
Arnaldo Carvalho de Melo e838c259e0 [CLASSES]: low_pc and high_pc attributes are Dwarf_Addr
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-28 09:36:39 -02:00
Arnaldo Carvalho de Melo 3ac4b868aa [CLASSES]: Introduce cus__load_dir()
To load directory trees, looking for files with a specified glob mask, calling
cus__load() on the ones that match and optionally recursively searching for
more matches in subdirectories.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-27 14:57:19 -02:00
Arnaldo Carvalho de Melo b0e2c51ec8 [CLASSES]: Allow struct cus instances to share a list of defs and fwd_decls
So that we can extract bits from one and combine it bits from other instances,
like we'll do in ctracer, where we want to have a cus instance just to get the
kprobes definitions and forward declarations but not handle the methods in it.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-27 14:39:37 -02:00
Arnaldo Carvalho de Melo bc5728f294 [CLASSES]: Store the high and low pc addresses in inline_expansion
For the ranges cases we store the lowest low_pc (in the first range) and the
highest high_pc (in the last range).

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-26 11:44:05 -02:00
Arnaldo Carvalho de Melo 3e60a747e6 [CLASSES]: Use size_t for size variables
uint64_t is a bit excessive.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-24 22:27:22 -02:00
Arnaldo Carvalho de Melo 7483c767f4 [CLASSES]: 'type' is also a Dwarf_Off
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-24 12:18:14 -02:00
Arnaldo Carvalho de Melo 45c40e4b8d [CLASSES]: Use Dwarf_Off type for the cu_offset derived variables/members
This is part of a cleanup process were I'm revisiting the types used for
the various abstractions, using the correct libdw.h types.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-24 12:07:41 -02:00
Arnaldo Carvalho de Melo 30128e9d11 [CLASSES]: Use uint32_t for the cu id
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-24 12:00:07 -02:00
Arnaldo Carvalho de Melo 3ca40af1fd [CLASSES]: Add support for enums
Be it named enums such as:

/* include/linux/pid.h:7 */
enum pid_type {
	PIDTYPE_PID = 0,
	PIDTYPE_PGID = 1,
	PIDTYPE_SID = 2,
	PIDTYPE_MAX = 3,
};

Or nameless enums inside structs:

/* include/linux/journal-head.h:14 */
typedef struct transaction_s {
        journal_t *                t_journal;            /*     0     4 */
        tid_t                      t_tid;                /*     4     4 */
        enum {
		T_RUNNING = 0,
		T_LOCKED = 1,
		T_RUNDOWN = 2,
		T_FLUSH = 3,
		T_COMMIT = 4,
		T_FINISHED = 5,
	} t_state;                                       /*     8     4 */
        long unsigned int          t_log_start;          /*    12     4 */
<SNIP>
} transaction_t; /* size: 84, cachelines: 3 */
                 /* last cacheline: 20 bytes */

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-24 11:56:59 -02:00
Arnaldo Carvalho de Melo 82692a819d [CLASSES]: Export cus__emit_fwd_decl
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-23 23:33:37 -02:00
Arnaldo Carvalho de Melo 149f4f81ed [CLASSES]: Introduce functions to rebuild structs, typedefs, etc
So that we can build a module that doesn't uses #includes to get these
definitions.

More work to be done for enums, etc, but this already is enough for
ctracer to handle tracing the sk_buff methods in vmlinux.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-23 19:29:27 -02:00
Arnaldo Carvalho de Melo af9adf0b9a [CLASSES]: Introduce cus__find_function_by_name
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-23 18:46:05 -02:00
Arnaldo Carvalho de Melo 7d581ce17c [CLASSES]: Introduce list heads for definitions and forward declarations
In struct cus, that will be used when rebuilding class definitions for
enums, struct pointers, struct definitions, etc, in ctracer for a start.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-23 18:30:48 -02:00
Arnaldo Carvalho de Melo 66ef6a39ba [CLASSES]: Add optional prefix and suffix parameters to class__print
That will be used when typedefs are being emitted, etc.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-23 18:09:47 -02:00
Arnaldo Carvalho de Melo 27af1f615b [CLASSES]: Introduce parameter__names
Some rework is needed to make class_member__names and parameter__names to share
more code, but there are things like bitfields that are exclusive to
class_member entries, etc.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-20 20:40:13 -02:00
Arnaldo Carvalho de Melo 973d243189 [CLASSES]: Introduce tag__fwd_decl
To emit forward declarations for types, used in ctracer.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-20 14:10:07 -02:00
Arnaldo Carvalho de Melo e15d528941 [CLASSES]: Add a 'visited' flag to struct class
So that tools can mark it as being processed already, such as when ctracer
needs to emit forward declarations for types in function parameters or return
types.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-20 13:49:51 -02:00
Arnaldo Carvalho de Melo 3e7e387ddb [CLASSES]: Move passing the object file name from cus__new to cus__load
So that we can load many object files, that is what the next csets will
do, to recursively look for files with debug info in a build tree, such
as the kernel one.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-20 12:35:45 -02:00
Arnaldo Carvalho de Melo 4a015cf738 [CLASSES]: Add list nodes to struct cu and function to be used by tools
Any tool can use it, first one will be ctracer, the class tracer.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-20 12:07:09 -02:00
Arnaldo Carvalho de Melo 5cb0779231 [CLASSES]: Pass the cookie to the filter in cu__for_each_function
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-20 12:05:29 -02:00
Arnaldo Carvalho de Melo 5484abff49 [CLASSES]: Move function__has_parameter_of_type from pfunct to libclasses
Will be used by a new tool, ctracer.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-20 12:03:12 -02:00
Arnaldo Carvalho de Melo 0dd2519bff [CLASSES]: Export class__name
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-19 09:11:17 -02:00
Arnaldo Carvalho de Melo a7f819ccb2 [CLASSES]: Remove some now unused functions
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-18 17:14:31 -02:00
Arnaldo Carvalho de Melo bd4dfbccb9 [CLASSES]: Add a filter to cu__for_each_function
Same purpose as in the one in cu__for_each_class.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-18 15:35:31 -02:00
Arnaldo Carvalho de Melo e70860fe11 [CLASSES]: Constify print routines class parameter
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-18 09:29:41 -02:00
Arnaldo Carvalho de Melo b515ca2386 [CLASSES]: Support multidimensional arrays
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-08 12:58:46 -02:00
Arnaldo Carvalho de Melo b45b9f6a95 [CLASSES]: Add a ->declaration member to struct class
For cases where the compiler doesn't emits the whole struct definition for
things like base classes that don't have any of its members acessed, just the
ones in its descendants.

Will be used to avoid emiting hole anottations, since we don't have the
size of these classes we can't say if its smaller than the space allocated
by the compiler.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-07 20:54:45 -02:00
Arnaldo Carvalho de Melo 41f58c52ca [CLASSES]: Make tag_name return "class" if object file is C++
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-07 17:21:52 -02:00
Arnaldo Carvalho de Melo 82892cd9dd [CLASSES]: First stab at implementing class__find_bit_hole
This new function searches the first member before the one being traversed that
has a bit hole (or byte_hole, I've just normalised it on bits to make it
generic) that can be used to combine with the class_member at hand to possibly
kill a hole, possibly because for now it doesn't guarantees that moving the
member being traversed to just after the hole after the member returned by
class__find_bit_hole will indeed reduce the struct size, but its a good first
stab, next csets should provide a member to start from so that we can try to
find other holes after the one that proved not enough to reduce the struct
size.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-07 16:11:47 -02:00
Arnaldo Carvalho de Melo a373c28ba9 [CLASSES]: Find bit holes
An example is worth a thousand words, look for "XXX ... bit hole, try to pack"
and the stats at the bottom:

[acme@newtoy net-2.6]$ pahole ../OUTPUT/qemu/net-2.6/fs/inode.o task_struct
/* include2/asm/system.h:11 */
struct task_struct {
        volatile long int          state;                /*     0     4 */
        struct thread_info *       thread_info;          /*     4     4 */
        atomic_t                   usage;                /*     8     4 */
        long unsigned int          flags;                /*    12     4 */
        long unsigned int          ptrace;               /*    16     4 */
        int                        lock_depth;           /*    20     4 */
        int                        load_weight;          /*    24     4 */
        int                        prio;                 /*    28     4 */
        /* --- cacheline 1 boundary (32 bytes) --- */
        int                        static_prio;          /*    32     4 */
        int                        normal_prio;          /*    36     4 */
        struct list_head           run_list;             /*    40     8 */
        struct prio_array *        array;                /*    48     4 */
        short unsigned int         ioprio;               /*    52     2 */

        /* XXX 2 bytes hole, try to pack */

        long unsigned int          sleep_avg;            /*    56     4 */
        long long unsigned int     timestamp;            /*    60     8 */
        /* --- cacheline 2 boundary (64 bytes) was 4 bytes ago --- */
        long long unsigned int     last_ran;             /*    68     8 */
        long long unsigned int     sched_time;           /*    76     8 */
        enum sleep_type            sleep_type;           /*    84     4 */
        long unsigned int          policy;               /*    88     4 */
        cpumask_t                  cpus_allowed;         /*    92     4 */
        /* --- cacheline 3 boundary (96 bytes) --- */
        unsigned int               time_slice;           /*    96     4 */
        unsigned int               first_time_slice;     /*   100     4 */
        struct list_head           tasks;                /*   104     8 */
        struct list_head           ptrace_children;      /*   112     8 */
        struct list_head           ptrace_list;          /*   120     8 */
        /* --- cacheline 4 boundary (128 bytes) --- */
        struct mm_struct *         mm;                   /*   128     4 */
        struct mm_struct *         active_mm;            /*   132     4 */
        struct linux_binfmt *      binfmt;               /*   136     4 */
        long int                   exit_state;           /*   140     4 */
        int                        exit_code;            /*   144     4 */
        int                        exit_signal;          /*   148     4 */
        int                        pdeath_signal;        /*   152     4 */
        long unsigned int          personality;          /*   156     4 */
        /* --- cacheline 5 boundary (160 bytes) --- */
        unsigned int               did_exec:1;           /*   160     4 */

        /* XXX 31 bits hole, try to pack */

        pid_t                      pid;                  /*   164     4 */
        pid_t                      tgid;                 /*   168     4 */
        struct task_struct *       real_parent;          /*   172     4 */
        struct task_struct *       parent;               /*   176     4 */
        struct list_head           children;             /*   180     8 */
        struct list_head           sibling;              /*   188     8 */
        /* --- cacheline 6 boundary (192 bytes) was 4 bytes ago --- */
        struct task_struct *       group_leader;         /*   196     4 */
        struct pid_link            pids[3];              /*   200    36 */
        /* --- cacheline 7 boundary (224 bytes) was 12 bytes ago --- */
        struct list_head           thread_group;         /*   236     8 */
        struct completion *        vfork_done;           /*   244     4 */
        int *                      set_child_tid;        /*   248     4 */
        int *                      clear_child_tid;      /*   252     4 */
        /* --- cacheline 8 boundary (256 bytes) --- */
        long unsigned int          rt_priority;          /*   256     4 */
        cputime_t                  utime;                /*   260     4 */
        cputime_t                  stime;                /*   264     4 */
        long unsigned int          nvcsw;                /*   268     4 */
        long unsigned int          nivcsw;               /*   272     4 */
        struct timespec            start_time;           /*   276     8 */
        long unsigned int          min_flt;              /*   284     4 */
        /* --- cacheline 9 boundary (288 bytes) --- */
        long unsigned int          maj_flt;              /*   288     4 */
        cputime_t                  it_prof_expires;      /*   292     4 */
        cputime_t                  it_virt_expires;      /*   296     4 */
        long long unsigned int     it_sched_expires;     /*   300     8 */
        struct list_head           cpu_timers[3];        /*   308    24 */
        /* --- cacheline 10 boundary (320 bytes) was 12 bytes ago --- */
        uid_t                      uid;                  /*   332     4 */
        uid_t                      euid;                 /*   336     4 */
        uid_t                      suid;                 /*   340     4 */
        uid_t                      fsuid;                /*   344     4 */
        gid_t                      gid;                  /*   348     4 */
        /* --- cacheline 11 boundary (352 bytes) --- */
        gid_t                      egid;                 /*   352     4 */
        gid_t                      sgid;                 /*   356     4 */
        gid_t                      fsgid;                /*   360     4 */
        struct group_info *        group_info;           /*   364     4 */
        kernel_cap_t               cap_effective;        /*   368     4 */
        kernel_cap_t               cap_inheritable;      /*   372     4 */
        kernel_cap_t               cap_permitted;        /*   376     4 */
        unsigned int               keep_capabilities:1;  /*   380     4 */

        /* XXX 31 bits hole, try to pack */

        /* --- cacheline 12 boundary (384 bytes) --- */
        struct user_struct *       user;                 /*   384     4 */
        struct key *               request_key_auth;     /*   388     4 */
        struct key *               thread_keyring;       /*   392     4 */
        unsigned char              jit_keyring;          /*   396     1 */
        unsigned char              fpu_counter;          /*   397     1 */

        /* XXX 2 bytes hole, try to pack */

        int                        oomkilladj;           /*   400     4 */
        char                       comm[16];             /*   404    16 */
        /* --- cacheline 13 boundary (416 bytes) was 4 bytes ago --- */
        int                        link_count;           /*   420     4 */
        int                        total_link_count;     /*   424     4 */
        struct sysv_sem            sysvsem;              /*   428     4 */
        struct thread_struct       thread;               /*   432   656 */
        /* --- cacheline 34 boundary (1088 bytes) --- */
        struct fs_struct *         fs;                   /*  1088     4 */
        struct files_struct *      files;                /*  1092     4 */
        struct nsproxy *           nsproxy;              /*  1096     4 */
        struct signal_struct *     signal;               /*  1100     4 */
        struct sighand_struct *    sighand;              /*  1104     4 */
        sigset_t                   blocked;              /*  1108     8 */
        sigset_t                   real_blocked;         /*  1116     8 */
        /* --- cacheline 35 boundary (1120 bytes) was 4 bytes ago --- */
        sigset_t                   saved_sigmask;        /*  1124     8 */
        struct sigpending          pending;              /*  1132    16 */
        long unsigned int          sas_ss_sp;            /*  1148     4 */
        /* --- cacheline 36 boundary (1152 bytes) --- */
        size_t                     sas_ss_size;          /*  1152     4 */
        int                        (*notifier)();        /*  1156     4 */
        void *                     notifier_data;        /*  1160     4 */
        sigset_t *                 notifier_mask;        /*  1164     4 */
        void *                     security;             /*  1168     4 */
        struct audit_context *     audit_context;        /*  1172     4 */
        seccomp_t                  seccomp;              /*  1176     0 */
        u32                        parent_exec_id;       /*  1176     4 */
        u32                        self_exec_id;         /*  1180     4 */
        /* --- cacheline 37 boundary (1184 bytes) --- */
        spinlock_t                 alloc_lock;           /*  1184    40 */
        /* --- cacheline 38 boundary (1216 bytes) was 8 bytes ago --- */
        spinlock_t                 pi_lock;              /*  1224    40 */
        /* --- cacheline 39 boundary (1248 bytes) was 16 bytes ago --- */
        struct plist_head          pi_waiters;           /*  1264    20 */
        /* --- cacheline 40 boundary (1280 bytes) was 4 bytes ago --- */
        struct rt_mutex_waiter *   pi_blocked_on;        /*  1284     4 */
        struct mutex_waiter *      blocked_on;           /*  1288     4 */
        unsigned int               irq_events;           /*  1292     4 */
        int                        hardirqs_enabled;     /*  1296     4 */
        long unsigned int          hardirq_enable_ip;    /*  1300     4 */
        unsigned int               hardirq_enable_event; /*  1304     4 */
        long unsigned int          hardirq_disable_ip;   /*  1308     4 */
        /* --- cacheline 41 boundary (1312 bytes) --- */
        unsigned int               hardirq_disable_event; /*  1312     4 */
        int                        softirqs_enabled;     /*  1316     4 */
        long unsigned int          softirq_disable_ip;   /*  1320     4 */
        unsigned int               softirq_disable_event; /*  1324     4 */
        long unsigned int          softirq_enable_ip;    /*  1328     4 */
        unsigned int               softirq_enable_event; /*  1332     4 */
        int                        hardirq_context;      /*  1336     4 */
        int                        softirq_context;      /*  1340     4 */
        /* --- cacheline 42 boundary (1344 bytes) --- */
        u64                        curr_chain_key;       /*  1344     8 */
        int                        lockdep_depth;        /*  1352     4 */
        struct held_lock           held_locks[30];       /*  1356  1200 */
        /* --- cacheline 79 boundary (2528 bytes) was 28 bytes ago --- */
        unsigned int               lockdep_recursion;    /*  2556     4 */
        /* --- cacheline 80 boundary (2560 bytes) --- */
        void *                     journal_info;         /*  2560     4 */
        struct reclaim_state *     reclaim_state;        /*  2564     4 */
        struct backing_dev_info *  backing_dev_info;     /*  2568     4 */
        struct io_context *        io_context;           /*  2572     4 */
        long unsigned int          ptrace_message;       /*  2576     4 */
        siginfo_t *                last_siginfo;         /*  2580     4 */
        wait_queue_t *             io_wait;              /*  2584     4 */
        u64                        rchar;                /*  2588     8 */
        /* --- cacheline 81 boundary (2592 bytes) was 4 bytes ago --- */
        u64                        wchar;                /*  2596     8 */
        u64                        syscr;                /*  2604     8 */
        u64                        syscw;                /*  2612     8 */
        struct robust_list_head *  robust_list;          /*  2620     4 */
        /* --- cacheline 82 boundary (2624 bytes) --- */
        struct list_head           pi_state_list;        /*  2624     8 */
        struct futex_pi_state *    pi_state_cache;       /*  2632     4 */
        atomic_t                   fs_excl;              /*  2636     4 */
        struct rcu_head            rcu;                  /*  2640     8 */
        struct pipe_inode_info *   splice_pipe;          /*  2648     4 */
}; /* size: 2656, cachelines: 83 */
   /* sum members: 2648, holes: 2, sum holes: 4 */
   /* bit holes: 2, sum bit holes: 62 bits */
   /* padding: 4 */

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-07 12:26:50 -02:00
Arnaldo Carvalho de Melo 5c777371cd [CLASSES]: Make cu__for_each_class receive a filter
Same semantic as in the cus__for_each_cu filter.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-01 00:00:24 -02:00
Arnaldo Carvalho de Melo e5a400d01f [CLASSES]: Make cus__for_each_cu receive an optional filter
To simplify the callsites and make implementing the same thing on the other
dwarves (prefcnt, pfunct, etc) easy.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-30 23:48:34 -02:00
Arnaldo Carvalho de Melo b31090f722 [CLASSES]: Move more stuff to the lexblock namespace
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-20 16:51:42 -02:00
Arnaldo Carvalho de Melo 6a3cc448d1 [CLASSES]: Introduce struct lexblock
To represent DW_TAG_lexical_block, for now just group the lists of
labels, inline expansions and variables, struct function now has
the root of the tree as ->lexblock.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-20 16:38:47 -02:00
Arnaldo Carvalho de Melo 460c5d91f4 [CLASSES]: Implement DW_TAG_label full support
And use it in function__print:

[acme@newtoy net-2.6.20]$ pfunct -Ti net/ipv4/tcp_ipv4.o tcp_v4_err

/* net/ipv4/tcp_ipv4.c:352 */
void tcp_v4_err(struct sk_buff * skb, u32 info);
{
        struct iphdr * iph;                                           //   353
        struct tcphdr * th;                                           //   354
        struct tcp_sock * tp;                                         //   355
        struct inet_sock * inet;                                      //   356
        int type;                                                     //   357
        int code;                                                     //   358
        struct sock * sk;                                             //   359
        __u32 seq;                                                    //   360
        int err;                                                      //   361
        inet_lookup();                                                //   368
        inet_iif();                                                   //   368
        inet_twsk_put();                                              //   375
        __fswab32();                                                  //   390
        do_pmtu_discovery();                                          //   410
        struct request_sock * req;                                    //   424
        struct request_sock * * prev;                                 //   424
        inet_csk_reqsk_queue_drop();                                  //   450
        tcp_done();                                                   //   462

out:                                                                  //   493
        sock_put();                                                   //   495
}

/* size: 1538, variables: 11, goto labels: 1, inline expansions: 10 (1066 bytes) */

Now to support DW_TAG_lexical_block, then to study libelf to fill in the
missing parts with assembly (or C snippets automagically rebuilt from the
assembly ;) ).

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-20 16:17:42 -02:00
Arnaldo Carvalho de Melo 139cfd3318 [CLASSES]: Enhance function__print
Introducing function__print_body, that orders the tags in a function by the
souce code line where it was declared or inlined.

This finally takes advantage of the struct tag "superclass", more to come in
the form of lexical blocks and goto labels.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-20 15:43:39 -02:00
Arnaldo Carvalho de Melo a1c8aefe4e [CLASSES]: Support DW_TAG_unspecified_parameters
aka "..."

[acme@newtoy net-2.6.20]$ pfunct kernel/panic.o panic
/* kernel/panic.c:61 */
void panic(const char  * fmt, ...);
/* size: 241, variables: 3, inline expansions: 1 (3 bytes) */

[acme@newtoy net-2.6.20]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-18 21:15:36 -02:00
Arnaldo Carvalho de Melo 179e15d553 [PFUNCT]: Differentiate inlining cases
Following what is in the DWARF2 specs:

Name                          Meaning
-----------------------------------------------------------------------------
DW_INL_not_inlined            Not declared inline nor inlined by the compiler
DW_INL_inlined                Not declared inline but inlined by the compiler
DW_INL_declared_not_inlined   Declared inline but not inlined by the compiler
DW_INL_declared_inlined       Declared inline and inlined by the compiler

Take advantae of this and use it in a new pfunct option: --cc_inlined, to
show which functions were of the DW_INL_inlined type.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-18 19:02:55 -02:00
Arnaldo Carvalho de Melo bff3938037 [CLASSES]: Introduce struct function & struct parameter
And helper routines, so as to separate DW_TAG_subprogram from
the type tags (DW_TAG_structure_type, basic_type, etc).

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-18 14:33:48 -02:00
Arnaldo Carvalho de Melo 5afa478d8d [CLASSES]: Introduce struct tag
This should have been done from the start: all DW_TAG_s will be represented by
structs that has as its first member a struct tag, so that we can fully
represent the DWARF information, following csets will take continue the
restructuring.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-18 11:54:02 -02:00
Arnaldo Carvalho de Melo 47845f0f9b [PFUNCT]: Implement --externals
That uses the DW_AT_external attribute, that tells if the DW_TAG_subprogram
(a function) is visible externally.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-17 23:43:08 -02:00
Arnaldo Carvalho de Melo d3b9b9bfcf [CLASSES]: Add backpointer to class in inline_expansion
And several assorted tidy-ups.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-13 00:31:48 -02:00
Arnaldo Carvalho de Melo c49c7c8bee [CLASSES] class_member: add backpointer to the class
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-12 17:52:03 -02:00
Arnaldo Carvalho de Melo 9490088ae0 [CLASSES]: Use the struct cu backpointer
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-12 17:33:37 -02:00
Arnaldo Carvalho de Melo 570a00b29f [CLASSES] classes: Add a backpoint to the CU that owns the class
This fixes a problem with codiff usage of the ->class_to_diff member, as we
were looking at a different CU than the one intended, so we'd have to have a
pointer to the CU associated with ->class_to_diff, heck, its time to have this
backpointer :-)

Now to audit the rest of the code to look for simplifications since we now have
this backpointer and thus don't need to pass CU pointers around.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-12 16:59:47 -02:00
Arnaldo Carvalho de Melo d99bee8d7b [CODIFF]: Detect and print all sorts of changes in structs
[acme@newtoy examples]$ cat struct.c

static struct foo {
	char	       a:2;
	unsigned int   b;
	unsigned long  c;
	unsigned long  d;
	unsigned long  e;
} bar;

int main(int argc, char *argv[])
{
    printf("%d", bar.a);
}
[acme@newtoy examples]$

Then change "a:2" to "a:4":

[acme@newtoy examples]$ codiff -V old_struct new_struct
struct.c:
  struct foo |   +0
    a:2;
     from: char                  /*     0(6)     1(2) */
     to:   char                  /*     0(4)     1(4) */
 1 struct changed

Now, on top of that move a after b:

[acme@newtoy examples]$ codiff -V old_struct new_struct
struct.c:
  struct foo |   +0
    a:2;
     from: char                  /*     0(6)     1(2) */
     to:   char                  /*     4(4)     1(4) */
    b;
     from: unsigned int          /*     4(0)     4(0) */
     to:   unsigned int          /*     0(0)     4(0) */
 1 struct changed
[acme@newtoy examples]$

Move it back a to before b and change the type of e without changing its size,
i.e. from unsigned long to long:

[acme@newtoy examples]$ codiff -V old_struct new_struct
struct.c:
  struct foo |   +0
    a:2;
     from: char                  /*     0(6)     1(2) */
     to:   char                  /*     0(4)     1(4) */
    e;
     from: long unsigned int     /*    16(0)     4(0) */
     to:   long int              /*    16(0)     4(0) */
 1 struct changed
[acme@newtoy examples]$

Now on top of this lets delete the c member:

[acme@newtoy examples]$ codiff -V old_struct new_struct
struct.c:
  struct foo |   -4
   nr_members: -1
    -long unsigned int          c;                    /*     8     4 */
    a:2;
     from: char                  /*     0(6)     1(2) */
     to:   char                  /*     0(4)     1(4) */
    d;
     from: long unsigned int     /*    12(0)     4(0) */
     to:   long unsigned int     /*     8(0)     4(0) */
    e;
     from: long unsigned int     /*    16(0)     4(0) */
     to:   long int              /*    12(0)     4(0) */
 1 struct changed
[acme@newtoy examples]$

WOW, many changes, what an ABI breakage, no? :-)

It started as:

[acme@newtoy examples]$ pahole old_struct foo
/* /home/acme/pahole/examples/struct.c:3 */
struct foo {
        char                       a:2;                  /*     0     1 */

        /* XXX 3 bytes hole, try to pack */

        unsigned int               b;                    /*     4     4 */
        long unsigned int          c;                    /*     8     4 */
        long unsigned int          d;                    /*    12     4 */
        long unsigned int          e;                    /*    16     4 */
}; /* size: 20, sum members: 17, holes: 1, sum holes: 3 */

And ended up as:

[acme@newtoy examples]$ pahole new_struct foo
/* /home/acme/pahole/examples/struct.c:3 */
struct foo {
        char                       a:4;                  /*     0     1 */

        /* XXX 3 bytes hole, try to pack */

        unsigned int               b;                    /*     4     4 */
        long unsigned int          d;                    /*     8     4 */
        long int                   e;                    /*    12     4 */
}; /* size: 16, sum members: 13, holes: 1, sum holes: 3 */

[acme@newtoy examples]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-12 15:07:21 -02:00
Arnaldo Carvalho de Melo c322523dfd [CODIFF]: Add --verbose to show diff details (members removed, etc)
First step:

Show if struct members were removed or added:

[acme@newtoy net-2.6.20]$ codiff -sV /tmp/ipv6.ko.before /tmp/ipv6.ko.after
<SNIP>
/pub/scm/linux/kernel/git/acme/net-2.6.20/net/ipv6/tcp_ipv6.c:
  struct inet_sock            |   -4
   nr_members: -1
  struct inet_connection_sock |   -4
  struct tcp_sock             |   -4
  struct tcp6_sock            |   -4
 4 structs changed
<SNIP>

Oh, so struct inet_sock must be one of the members of the other structs that
haven't had changes in its number of members? Yes, this is the case :-)

Now lets see _which_ members were removed, added or had its type changed
causing a reduction in the struct size.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-12 12:56:52 -02:00
Arnaldo Carvalho de Melo e4f5c8395c [CODIFF]: Show structure changes
[acme@newtoy net-2.6.20]$ codiff /tmp/ipv6.ko.before /tmp/ipv6.ko.after | head -12
/pub/scm/linux/kernel/git/acme/net-2.6.20/net/ipv6/af_inet6.c:
  struct inet_sock        |   -4
 1 struct changed
  inet6_init              |  +50
  inet6_create            |  -15
  inet6_getname           |  +13
  inet6_sk_rebuild_header |   +5
 4 functions changed, 68 bytes added, 15 bytes removed

/pub/scm/linux/kernel/git/acme/net-2.6.20/net/ipv6/anycast.c:
  ipv6_sock_ac_join |   +7
 1 function changed, 7 bytes added
[acme@newtoy net-2.6.20]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-12 12:29:33 -02:00