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