Commit Graph

101 Commits

Author SHA1 Message Date
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
c372555a6c [CLASSES]: Return NULL in cu__find_class_by_id if tag.type == 0
I.e. if the type is void, avoiding looking the whole list for something
that is not there.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-20 14:02:05 -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
a9d464021d [CLASSES]: Make class__name return "void" when passed a NULL class
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-19 09:20:52 -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
6d02afd548 [CLASSES]: Remove newlines at the end of class__print
Let the callers decide if they want to do it.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-18 10:20:57 -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
8330d47a1a [CLASSES]: Handle bitfields combined with one or two byte members
See the comment in the code.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-14 16:49:06 -02:00
Arnaldo Carvalho de Melo
1578e231f9 [CLASSES]: Tidy up the holes comments
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-14 16:00:28 -02:00
Arnaldo Carvalho de Melo
bb980f7fed [CLASSES]: Whitespace fixups
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-14 13:18:07 -02:00
Arnaldo Carvalho de Melo
a779f9a7c9 [CLASSES]: Fix the bit hole finding logic
We should check if we're in a new byte offset, i.e. the previous bitfield is
gone, now it works well when two bitfields are found one after the other, like
in struct sk_buff.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-14 13:13:14 -02:00
Helio Chissini de Castro
75a3425a9a [MAKEFILE]: Use cmake in the build process
Signed-off-by: Helio Chissini de Castro <helio@mandriva.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-12 00:37:23 -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
9d21d3d72d [CLASSES]: Add support for DW_TAG_inheritance
So that languages such as C++ can have its inheritance concepts
covered, example:

[acme@newtoy examples]$ pahole qsettings.o QSettingsPrivate
/* io/qsettings_p.h:159 */
class QSettingsPrivate {
        class QObjectPrivate;        /* ancestor class */  /*  0 0 */

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

        /* --- cacheline 1 boundary (32 bytes) was 24 bytes ago --- */
        class QStack<QSettingsGroup> groupStack;           /* 56 4 */
        class QString                groupPrefix;          /* 60 4 */
        /* --- cacheline 2 boundary (64 bytes) --- */
        int                          spec;                 /* 64 4 */
        bool                         fallbacks;            /* 68 1 */
        bool                         pendingChanges;       /* 69 1 */

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

        enum Status                  status;               /* 72 4 */
}; /* size: 76, cachelines: 3 */
   /* sum members: 18, holes: 2, sum holes: 58 */
   /* last cacheline: 12 bytes */

Nevermind about the "/* XXX 56 bytes hole, try to pack */" and sizeof(class
QObjectPrivate) being zero, its just gcc compressing the DWARF tags avoiding
including definitions that are not used in this specific object file, i.e.
there are not accesses to 'class QObjectPrivate' members.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-07 20:00:45 -02:00
Arnaldo Carvalho de Melo
fd1b4cadc2 [CLASSES]: Print cacheline boundary at the end of a struct too
Useful for structs where cacheline crossings happens on the last
member:

[acme@newtoy net-2.6]$ pahole --cacheline 32 net/ipv4/route.o hh_cache
/* /pub/scm/linux/kernel/git/acme/net-2.6/include/linux/netdevice.h:193 */
struct hh_cache {
        struct hh_cache *  hh_next;          /*  0   4 */
        atomic_t           hh_refcnt;        /*  4   4 */
        __be16             hh_type;          /*  8   2 */
        u16                hh_len;           /* 10   2 */
        int                (*hh_output)();   /* 12   4 */
        rwlock_t           hh_lock;          /* 16   0 */
        long unsigned int  hh_data[24];      /* 16  96 */
        /* --- cacheline 3 boundary (96 bytes) was 16 bytes ago --- */
}; /* size: 112, cachelines: 4 */
   /* last cacheline: 16 bytes */

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-07 19:20:46 -02:00
Arnaldo Carvalho de Melo
d479b9c8e5 [CLASSES]: Disambiguate the cu__find_class_by_name
We want just DW_TAG_structure_type classes, but for now there are
enums, C++ inline classes, etc, have to fix this later.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-07 18:40:00 -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
ff0dc936d7 [CLASSES]: Tidy up holes printing, plural form
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-07 13:24:18 -02:00
Arnaldo Carvalho de Melo
2ac0afbf8e [CLASSES]: Tidy up holes annotations
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-07 13:07:22 -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
fb4fed3164 [CLASSES]: Fix cacheline boundary crossings
I not taking into account the sum of holes, so the math drifted when holes were
present.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-07 11:26:48 -02:00
Arnaldo Carvalho de Melo
8d19574248 [CLASSES]: Improve cacheline boundary printing
Now we show more cacheline boundaries by looking at when we cross cachelines,
not just when there is a exact cacheline boundary, an (long) example to
clarify:

[acme@newtoy net-2.6]$ pahole ../OUTPUT/qemu/net-2.6/fs/built-in.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 ----- */
        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 was 2 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 */
        unsigned int               time_slice;           /*    96     4 */
        /* ----- cacheline 3 boundary was 2 bytes ago ----- */
        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 */
        struct mm_struct *         mm;                   /*   128     4 */
        /* ----- cacheline 4 boundary was 2 bytes ago ----- */
        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 */
        unsigned int               did_exec:1;           /*   160     4 */
        /* ----- cacheline 5 boundary was 2 bytes ago ----- */
        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 was 2 bytes ago ----- */
        struct task_struct *       group_leader;         /*   196     4 */
        struct pid_link            pids[3];              /*   200    36 */
        /* ----- cacheline 7 boundary was 10 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 */
        long unsigned int          rt_priority;          /*   256     4 */
        /* ----- cacheline 8 boundary was 2 bytes ago ----- */
        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 */
        long unsigned int          maj_flt;              /*   288     4 */
        /* ----- cacheline 9 boundary was 2 bytes ago ----- */
        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 was 10 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 */
        gid_t                      egid;                 /*   352     4 */
        /* ----- cacheline 11 boundary was 2 bytes ago ----- */
        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 */
        struct user_struct *       user;                 /*   384     4 */
        /* ----- cacheline 12 boundary was 2 bytes ago ----- */
        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 ----- */
        int                        link_count;           /*   420     4 */
        int                        total_link_count;     /*   424     4 */
        struct sysv_sem            sysvsem;              /*   428     4 */
        struct thread_struct       thread;               /*   432   656 */
        /* ----- cacheline 33 boundary was 28 bytes ago ----- */
        struct fs_struct *         fs;                   /*  1088     4 */
        /* ----- cacheline 34 boundary ----- */
        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 ----- */
        sigset_t                   saved_sigmask;        /*  1124     8 */
        struct sigpending          pending;              /*  1132    16 */
        long unsigned int          sas_ss_sp;            /*  1148     4 */
        size_t                     sas_ss_size;          /*  1152     4 */
        /* ----- cacheline 36 boundary ----- */
        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 */
        spinlock_t                 alloc_lock;           /*  1184    40 */
        /* ----- cacheline 38 boundary was 4 bytes ago ----- */
        spinlock_t                 pi_lock;              /*  1224    40 */
        /* ----- cacheline 39 boundary was 12 bytes ago ----- */
        struct plist_head          pi_waiters;           /*  1264    20 */
        /* ----- cacheline 40 boundary ----- */
        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 */
        unsigned int               hardirq_disable_event; /*  1312     4 */
        /* ----- cacheline 41 boundary ----- */
        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 */
        u64                        curr_chain_key;       /*  1344     8 */
        /* ----- cacheline 42 boundary was 4 bytes ago ----- */
        int                        lockdep_depth;        /*  1352     4 */
        struct held_lock           held_locks[30];       /*  1356  1200 */
        /* ----- cacheline 79 boundary was 24 bytes ago ----- */
        unsigned int               lockdep_recursion;    /*  2556     4 */
        void *                     journal_info;         /*  2560     4 */
        /* ----- cacheline 80 boundary ----- */
        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 ----- */
        u64                        wchar;                /*  2596     8 */
        u64                        syscr;                /*  2604     8 */
        u64                        syscw;                /*  2612     8 */
        struct robust_list_head *  robust_list;          /*  2620     4 */
        struct list_head           pi_state_list;        /*  2624     8 */
        /* ----- cacheline 82 boundary was 4 bytes ago ----- */
        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, sum members: 2648, holes: 2, sum holes: 4, padding: 4, cachelines: 83 */

[acme@newtoy net-2.6]$

See the "cacheline 82 boundary was 4 bytes ago" type comments? They show cases
where members cross cachelines (in this case a 32 bytes cacheline was used, the
default when one doesn't specify one with --cacheline in the pahole cmd line).

This should help in reorganizing struct layouts to avoid bringing two
cachelines when, say, a 'int' member is accessed, i.e. better aligning the
members to avoid cacheline trashing.

One seemingly interesting idea now that we have this infrastructure is to write
code to suggest reorganizing a struct to avoid these cacheline boundary
crossings, kill holes, etc, this together with static analysis on binaries or
using sparse to look member usage patterns, i.e. if io_wait is almost always
used after wchar in task_struct, we would move them to be on the same
cacheline, of course there are cases where data dependency may be an obstacle,
we'd need blacklists to help the tool avoid moving these cases.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-07 04:20:42 -02:00
Arnaldo Carvalho de Melo
91c91fc822 [CLASSES]: Fix class__print_struct identation
No code changes

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-06 15:09:36 -02:00
Arnaldo Carvalho de Melo
441d9e0d5c [CLASSES]: Make class_member__print just print the member
Not printing the identation neither the newline, so that in the next csets
it'll be possible to show members that cross cacheline boundaries and also do
multiple levels of identation when we start supporting classes within classes
printing, to properly support C++.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-06 15:00:48 -02:00
Arnaldo Carvalho de Melo
2e0b628f16 [CLASSES]: Default to create classes for non structs too in class context
Supporting the C++ a bit more, enums, etc are basically handled inside
cu__process_class.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-06 14:23:54 -02:00
Arnaldo Carvalho de Melo
c6ad98fc08 [CLASSES]: First bits of C++ support
Now we support classes within classes, i.e. DW_TAG_structure_type entries
within DW_TAG_structure_type, a C++ feature, see the FIXME in the new code.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-06 11:35:21 -02:00
Bernhard Fischer
76bf0ada17 [CLASSES]: avoid mixing declarations and code
avoid mixing declarations and code to please ISO C90.

Signed-off-by: Bernhard Fischer <rep.nop@aon.at>
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-05 14:53:50 -02:00
Arnaldo Carvalho de Melo
b73c5c8d0f [CLASSES]: Print info about cacheline use
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-01 12:22:30 -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
71cdd0f588 [CLASSES]: Follow const types to get to the real type
Fixes a bug where 'const char name[29]' was being printed as
'const char name;'.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-29 18:33:22 -02:00
Arnaldo Carvalho de Melo
674d99e8fa [CLASSES]: Make cu__process_function receive a lexblock pointer
That starts with the root lexblock (&struct function->lexblock), next step will
be to create child lexblocks when finding DW_TAG_lexical_block tags.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-20 16:59:51 -02:00
Arnaldo Carvalho de Melo
2600c462c2 [CLASSES]: Move the lexblock initialization to lexblock__init
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-20 16:54:39 -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
78313d93e7 [CLASSES]: DW_TAG_inlined_subroutines doesn't have DW_AT_decl_{file,line}
It has DW_AT_call_{file,line}, fixed.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-20 00:36:11 -02:00
Arnaldo Carvalho de Melo
bcc85784fe [CLASSES]: Remove stray ; in function__print
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-20 00:26:04 -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