dwarves/ctfdwdiff

58 lines
1.0 KiB
Plaintext
Raw Normal View History

#!/bin/bash
results_dir=/tmp/ctfdwdiff
ctf_encoder: Convert DWARF functions to CTF Finally we can use the Elf file already opened in dwarf_load, call cu__for_each_cached_symtab_entry to iterate over the symtab entries, this iterator will first call dwfl_module_getsymtab, that will do the relocation that will allow us to go from the symtab address to the one in the DWARF DW_TAG_subprogram tag DW_AT_low_pc attribute. And voila, for a relatively complex single unit Linux kernel object file, kernel/sched.o, we go from: Just DWARF (gcc -g): $ ls -la kernel/sched.o 1979011 kernel/sched.o Then we run this to encode the CTF section: $ pahole -Z kernel/sched.o And get a file with both DWARF and CTF ELF sections: $ ls -la kernel/sched.o 2019848 kernel/sched.o We still need to encode the "OBJECTS", i.e. variables, but this gets us from 1979011 (just DWARF) to: $ strip--strip-debug kernel/sched.o $ ls -la kernel/sched.o -rw-rw-r-- 1 acme acme 507008 2009-03-30 23:01 kernel/sched.o 25% of the original size. Of course we don't have inline expansion information, parameter names, goto labels, etc, but should be good enough for most use cases. See, without DWARF data, if we ask for it to use DWARF, nothing will be printed, if we don't speficy the format, it will try first DWARF, it will not find anything, it will try CTF: $ pahole -F dwarf kernel/sched.o $ pahole -C seq_operations kernel/sched.o struct seq_operations { void * (*start)(struct seq_file *, loff_t *); /* 0 8 */ void (*stop)(struct seq_file *, void *); /* 8 8 */ void * (*next)(struct seq_file *, void *, loff_t *); /* 16 8 */ int (*show)(struct seq_file *, void *); /* 24 8 */ /* size: 32, cachelines: 1, members: 4 */ /* last cacheline: 32 bytes */ }; $ $ pfunct -Vi -f schedule kernel/sched.o void schedule(void); { /* low_pc=0xe01 */ }/* size: 83 */ $ Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-31 03:54:29 +02:00
diff_tool() {
local tool=$1
local dwarf_options=$2
local ctf_options=$3
local obj=$4
diff=$results_dir/$obj.$tool.diff
ctf=$results_dir/$obj.$tool.ctf.c
dwarf=$results_dir/$obj.$tool.dwarf.c
ctf_encoder: Convert DWARF functions to CTF Finally we can use the Elf file already opened in dwarf_load, call cu__for_each_cached_symtab_entry to iterate over the symtab entries, this iterator will first call dwfl_module_getsymtab, that will do the relocation that will allow us to go from the symtab address to the one in the DWARF DW_TAG_subprogram tag DW_AT_low_pc attribute. And voila, for a relatively complex single unit Linux kernel object file, kernel/sched.o, we go from: Just DWARF (gcc -g): $ ls -la kernel/sched.o 1979011 kernel/sched.o Then we run this to encode the CTF section: $ pahole -Z kernel/sched.o And get a file with both DWARF and CTF ELF sections: $ ls -la kernel/sched.o 2019848 kernel/sched.o We still need to encode the "OBJECTS", i.e. variables, but this gets us from 1979011 (just DWARF) to: $ strip--strip-debug kernel/sched.o $ ls -la kernel/sched.o -rw-rw-r-- 1 acme acme 507008 2009-03-30 23:01 kernel/sched.o 25% of the original size. Of course we don't have inline expansion information, parameter names, goto labels, etc, but should be good enough for most use cases. See, without DWARF data, if we ask for it to use DWARF, nothing will be printed, if we don't speficy the format, it will try first DWARF, it will not find anything, it will try CTF: $ pahole -F dwarf kernel/sched.o $ pahole -C seq_operations kernel/sched.o struct seq_operations { void * (*start)(struct seq_file *, loff_t *); /* 0 8 */ void (*stop)(struct seq_file *, void *); /* 8 8 */ void * (*next)(struct seq_file *, void *, loff_t *); /* 16 8 */ int (*show)(struct seq_file *, void *); /* 24 8 */ /* size: 32, cachelines: 1, members: 4 */ /* last cacheline: 32 bytes */ }; $ $ pfunct -Vi -f schedule kernel/sched.o void schedule(void); { /* low_pc=0xe01 */ }/* size: 83 */ $ Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-31 03:54:29 +02:00
$tool -F ctf $ctf_options $obj > $ctf
$tool -F dwarf $dwarf_options $obj > $dwarf
diff -up $dwarf $ctf > $diff
if [ -s $diff ] ; then
[ $# -gt 4 ] && vim $diff
exit 0
else
rm -f $diff $ctf $dwarf
fi
}
ctf_encoder: Convert DWARF functions to CTF Finally we can use the Elf file already opened in dwarf_load, call cu__for_each_cached_symtab_entry to iterate over the symtab entries, this iterator will first call dwfl_module_getsymtab, that will do the relocation that will allow us to go from the symtab address to the one in the DWARF DW_TAG_subprogram tag DW_AT_low_pc attribute. And voila, for a relatively complex single unit Linux kernel object file, kernel/sched.o, we go from: Just DWARF (gcc -g): $ ls -la kernel/sched.o 1979011 kernel/sched.o Then we run this to encode the CTF section: $ pahole -Z kernel/sched.o And get a file with both DWARF and CTF ELF sections: $ ls -la kernel/sched.o 2019848 kernel/sched.o We still need to encode the "OBJECTS", i.e. variables, but this gets us from 1979011 (just DWARF) to: $ strip--strip-debug kernel/sched.o $ ls -la kernel/sched.o -rw-rw-r-- 1 acme acme 507008 2009-03-30 23:01 kernel/sched.o 25% of the original size. Of course we don't have inline expansion information, parameter names, goto labels, etc, but should be good enough for most use cases. See, without DWARF data, if we ask for it to use DWARF, nothing will be printed, if we don't speficy the format, it will try first DWARF, it will not find anything, it will try CTF: $ pahole -F dwarf kernel/sched.o $ pahole -C seq_operations kernel/sched.o struct seq_operations { void * (*start)(struct seq_file *, loff_t *); /* 0 8 */ void (*stop)(struct seq_file *, void *); /* 8 8 */ void * (*next)(struct seq_file *, void *, loff_t *); /* 16 8 */ int (*show)(struct seq_file *, void *); /* 24 8 */ /* size: 32, cachelines: 1, members: 4 */ /* last cacheline: 32 bytes */ }; $ $ pfunct -Vi -f schedule kernel/sched.o void schedule(void); { /* low_pc=0xe01 */ }/* size: 83 */ $ Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-31 03:54:29 +02:00
diff_one() {
local obj=$1
diff_tool "pahole" "--flat_arrays --show_private_classes --fixup_silly_bitfields" " " $obj $2
diff_tool "pfunct" "-V --no_parm_names" "-V" $obj $2
ctf_encoder: Convert DWARF functions to CTF Finally we can use the Elf file already opened in dwarf_load, call cu__for_each_cached_symtab_entry to iterate over the symtab entries, this iterator will first call dwfl_module_getsymtab, that will do the relocation that will allow us to go from the symtab address to the one in the DWARF DW_TAG_subprogram tag DW_AT_low_pc attribute. And voila, for a relatively complex single unit Linux kernel object file, kernel/sched.o, we go from: Just DWARF (gcc -g): $ ls -la kernel/sched.o 1979011 kernel/sched.o Then we run this to encode the CTF section: $ pahole -Z kernel/sched.o And get a file with both DWARF and CTF ELF sections: $ ls -la kernel/sched.o 2019848 kernel/sched.o We still need to encode the "OBJECTS", i.e. variables, but this gets us from 1979011 (just DWARF) to: $ strip--strip-debug kernel/sched.o $ ls -la kernel/sched.o -rw-rw-r-- 1 acme acme 507008 2009-03-30 23:01 kernel/sched.o 25% of the original size. Of course we don't have inline expansion information, parameter names, goto labels, etc, but should be good enough for most use cases. See, without DWARF data, if we ask for it to use DWARF, nothing will be printed, if we don't speficy the format, it will try first DWARF, it will not find anything, it will try CTF: $ pahole -F dwarf kernel/sched.o $ pahole -C seq_operations kernel/sched.o struct seq_operations { void * (*start)(struct seq_file *, loff_t *); /* 0 8 */ void (*stop)(struct seq_file *, void *); /* 8 8 */ void * (*next)(struct seq_file *, void *, loff_t *); /* 16 8 */ int (*show)(struct seq_file *, void *); /* 24 8 */ /* size: 32, cachelines: 1, members: 4 */ /* last cacheline: 32 bytes */ }; $ $ pfunct -Vi -f schedule kernel/sched.o void schedule(void); { /* low_pc=0xe01 */ }/* size: 83 */ $ Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-31 03:54:29 +02:00
}
diff_dir() {
find . -type d | \
while read dir ; do
cd $dir
ls *.o 2> /dev/null |
while read obj ; do
ncus=$(readelf -wi $obj | grep DW_TAG_compile_unit | wc -l)
if [ $ncus -ne 1 ] ; then
continue
fi
echo $obj
ctf_encoder: Convert DWARF functions to CTF Finally we can use the Elf file already opened in dwarf_load, call cu__for_each_cached_symtab_entry to iterate over the symtab entries, this iterator will first call dwfl_module_getsymtab, that will do the relocation that will allow us to go from the symtab address to the one in the DWARF DW_TAG_subprogram tag DW_AT_low_pc attribute. And voila, for a relatively complex single unit Linux kernel object file, kernel/sched.o, we go from: Just DWARF (gcc -g): $ ls -la kernel/sched.o 1979011 kernel/sched.o Then we run this to encode the CTF section: $ pahole -Z kernel/sched.o And get a file with both DWARF and CTF ELF sections: $ ls -la kernel/sched.o 2019848 kernel/sched.o We still need to encode the "OBJECTS", i.e. variables, but this gets us from 1979011 (just DWARF) to: $ strip--strip-debug kernel/sched.o $ ls -la kernel/sched.o -rw-rw-r-- 1 acme acme 507008 2009-03-30 23:01 kernel/sched.o 25% of the original size. Of course we don't have inline expansion information, parameter names, goto labels, etc, but should be good enough for most use cases. See, without DWARF data, if we ask for it to use DWARF, nothing will be printed, if we don't speficy the format, it will try first DWARF, it will not find anything, it will try CTF: $ pahole -F dwarf kernel/sched.o $ pahole -C seq_operations kernel/sched.o struct seq_operations { void * (*start)(struct seq_file *, loff_t *); /* 0 8 */ void (*stop)(struct seq_file *, void *); /* 8 8 */ void * (*next)(struct seq_file *, void *, loff_t *); /* 16 8 */ int (*show)(struct seq_file *, void *); /* 24 8 */ /* size: 32, cachelines: 1, members: 4 */ /* last cacheline: 32 bytes */ }; $ $ pfunct -Vi -f schedule kernel/sched.o void schedule(void); { /* low_pc=0xe01 */ }/* size: 83 */ $ Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-31 03:54:29 +02:00
pahole -Z $obj
diff_one $obj $1
done
cd - > /dev/null
done
}
rm -rf $results_dir
mkdir $results_dir
if [ $# -lt 2 ] ; then
diff_dir
else
diff_one $*
fi