process to inspect generated assembly of a function

Andev debiandev at gmail.com
Fri Jun 6 21:02:26 EDT 2014


On Fri, Jun 6, 2014 at 1:26 PM, Nicholas Mc Guire <der.herr at hofr.at> wrote:
>
> in the kernel build system there is support for understanding assembler code
> by generating the .lst files which include the decoded assembler interleaved
> with the C source (roughly) making it easier to understand the code.
> Also --verbose-asm used when generating .s files in the kernel helps as gcc
> is creating variables that are not in your C-code and that can be confusing
> to decode if one does not see it from the names.
> finally looking at the source code can be challenging as there are many
> macros and build dependencies so its probably easier to look at the
> preprocessor output .i rather than the original C-source file.
>
> for kernel sources its:
>
> hofrat at rtl27:~/linux-stable# make defconfig
> *** Default configuration is based on 'x86_64_defconfig'
> #
> # configuration written to .config
> #
> hofrat at rtl27:~/linux-stable# make kernel/mutex.lst
> scripts/kconfig/conf --silentoldconfig Kconfig
> ...
>   HOSTCC  scripts/conmakehash
>   HOSTCC  scripts/sortextable
>   MKLST   kernel/mutex.lst
> hofrat at rtl27:~/linux-stable# more kernel/mutex.lst
> <snip>
> void
> __mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key)
> {
>         atomic_set(&lock->count, 1);
>         spin_lock_init(&lock->wait_lock);
>    b:   66 c7 47 04 00 00       movw   $0x0,0x4(%rdi)
>         lock->owner = current;
> }
> ...
> <snip>
>
> hofrat at rtl27:~/linux-stable# make kernel/mutex.s
> ...
>   CHK     include/generated/utsrelease.h
>   CALL    scripts/checksyscalls.sh
>   CC      kernel/mutex.s
> hofrat at rtl27:~/linux-stable# more kernel/mutex.s
> <snip>
> ...
>         .text
>         .p2align 4,,15
> .globl __mutex_init
>         .type   __mutex_init, @function
> __mutex_init:
>         pushq   %rbp    #
>         leaq    8(%rdi), %rax   #, D.20779
>         movl    $1, (%rdi)      #, <variable>.count.counter
>         movw    $0, 4(%rdi)     #, <variable>.wait_lock.D.3891.rlock
>         movq    $0, 24(%rdi)    #, <variable>.owner
>         movq    %rsp, %rbp      #,
>         movq    %rax, 8(%rdi)   # D.20779, <variable>.wait_list.next
>         movq    %rax, 16(%rdi)  # D.20779, <variable>.wait_list.prev
>         movq    $0, 32(%rdi)    #, <variable>.spin_mlock
>         leave
>         ret
>  ...
> <snip>
>
>  The variables named D.# are those that gcc created.
>  Note that the code looks different because of the #defines that were
>  resolved and translated in .s case but not in the .lst case.
>
>  having both the .s and the .lst file at hand along with the preprocessor
>  output generated by
>
>
> hofrat at rtl27:~/linux-stable# make kernel/mutex.i
> hofrat at rtl27:~/linux-stable# more kernel/mutex.i
> <snip>
>  ...
> void
> __mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key)
> {
>  atomic_set(&lock->count, 1);
>  do { spinlock_check(&lock->wait_lock); do { *(&(&lock->wait_lock)->rlock) = (raw_spinlock_t) { .raw_lock = { { 0 } }, }; } while (0); } while (0);
>  INIT_LIST_HEAD(&lock->wait_list);
>  mutex_clear_owner(lock);
>
>  lock->spin_mlock = ((void *)0);
>
>
>  do { } while (0);
> }
> ...
> <snip>
>
>  should allow you to figure out the details of what is going on in the assembler
>  code of your functions.
>
> thx!
> hofrat

Thanks a lot Nicholas. This is the easiest way I've seen to far!


-- 
Andev



More information about the Kernelnewbies mailing list