Bug 24431 - ELF reader can't interpret ksymtab with Kernel 4.19+
Since the commit
https://github.com/torvalds/linux/commit/
7290d58095712a89f845e1bca05334796dd49ed2
of the kernel, the format of the ksymtab section changed, so the ELF
reader of Libabigail cannot get the list of kernel symbols that are
meaningful to analyze.
In the new format, each ksymtab entry is now 32 bits length,
independently of if the kernel was built in 32 or 64 bits mode. This
way, 64 bit kernels save 32 bits per entry, from the ksymtab section
alone.
Also, note that the symbol address in the ksymtab entry is stored in a
"place-relative address" format. That means for a given symbol value
'Sym_Addr', the value which is stored at a given offset 'Off' of the
ksymtab secthion which address is Ksymtab_Addr is:
Sym_Addr - Ksymtab_Addr - Off.
This is what is meant by storing Sym_Addr in a "place-relative" manner.
One advantage, of course, is to make Sym_Addr take 32 bits, even on a
64 bits arch. Another advantage is that the resulting value doesn't
need to be relocated! So we don't need any relocation section either!
So lots of space saving.
This patch teaches the ELF reader into this new format.
* src/abg-dwarf-reader.cc (enum kernel_symbol_table_kind): Move this
enum at the top.
(enum ksymtab_format): Define new enum.
(read_context::{ksymtab_format_, ksymtab_entry_size_,
nb_ksymtab_entries_, nb_ksymtab_gpl_entries_}): Define new data
members.
(read_context::initiliaze): Initialize the new data members above.
(read_context::{get_ksymtab_format, get_ksymtab_symbol_value_size,
get_ksymtab_entry_size, get_nb_ksymtab_entries,
get_nb_ksymtab_gpl_entries,
maybe_adjust_sym_address_from_v4_19_ksymtab}): Define new member
functions.
(read_context::load_kernel_symbol_table): Support loading from
both pre and post v4.19 linux kernels with their different ksymtab
formats. Add more comments.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>