Issue
With KASLR enabled there will be an offset between symbol file and actual symbol location.
% cat /proc/kallsyms| grep '\<jiffies_64\>'
ffffffff86805000 D jiffies_64
% objdump -t /usr/lib/debug/boot/vmlinux-4.13.0-1-amd64 | grep '\<jiffies_64\>'
ffffffff81c05000 g O .data 0000000000000008 jiffies_64
Find the .text section location, so I can load the symbol file correctly:
% cat /proc/kallsyms | grep '\<_text\>'
ffffffff85c00000 T _text
But even if I loaded the symbol file at correction location:
% sudo gdb -c /proc/kcore
GNU gdb (Debian 8.0-1) 8.0
(gdb) add-symbol-file /usr/lib/debug/boot/vmlinux-4.13.0-1-amd64 0xffffffff85c00000
add symbol table from file "/usr/lib/debug/boot/vmlinux-4.13.0-1-amd64" at
.text_addr = 0xffffffff85c00000
(y or n) y
Reading symbols from /usr/lib/debug/boot/vmlinux-4.13.0-1-amd64...done.
GDB still giving the wrong symbol location:
(gdb) p &jiffies_64
$1 = (u64 *) 0xffffffff81c05000 <jiffies_64>
How do I force GDB to load the symbol at correct location ?
Solution
First, notice the second field in the line of jiffies_64
symbol.
# grep -w jiffies_64 /proc/kallsyms
ffffffffbb005000 D jiffies_64
The second field is the symbol type (see nm(1)
). In this case, D
means that the jiffies_64
symbol is located at the data segment.
You have loaded your vmlinux file and only specified the address of the text segment, but since jiffies_64
is not in the text segment but in the data segment, it didn't help you.
So first you need to find the start address of your kernel's data segment, which is the address of the _sdata
symbol in /proc/kallsyms
.
# grep -w _sdata /proc/kallsyms
ffffffffbb000000 D _sdata
Then you need to load your vmlinux file with the start address of the kernel's data segment.
# gdb -q -c /proc/kcore
(gdb) add-symbol-file /usr/lib/debug/boot/vmlinux-4.12.14-122.37-default.debug -s .data 0xffffffffbb000000
add symbol table from file "/usr/lib/debug/boot/vmlinux-4.12.14-122.37-default.debug" at
.data_addr = 0xffffffffbb000000
(y or n) y
Reading symbols from /usr/lib/debug/boot/vmlinux-4.12.14-122.37-default.debug...
(gdb) p &jiffies_64
$1 = (u64 *) 0xffffffffbb005000 <jiffies_64>
And - voila, now the address of jiffies_64
is 0xffffffffbb0050000
, which is exactly what you see in /proc/kallsyms
.
Answered By - aviro