This commit adds basic debuginfo support. It is "basic" in as much as
it does not try to parse the DWARF data to figure out which parts
pertain to the changed code. It simply includes all .debug_ and
.rela.debug_ section and strips out any rela entries that reference
unchanged symbols. This corrupts the debuginfo for unchanged symbols
but since they are not going to be included anyway, there should be no
way to reference that information.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
The recent module patching code has exposed some problems with our data
structures. We currently patch the funcs and dynrelas individually,
which is kind of scary now that different objects can be patched at
different times. Instead it's cleaner and safer to group them by
patched object.
This patch implements per-object patching and relocations by refactoring
the interfaces:
- Completely separate the create-diff-object <-> patch module interface
from the patch module <-> core module interface. create-diff-object
will include "kpatch-patch.h" but not "kpatch.h". Thus,
create-diff-object has no knowledge about the core module's
interfaces, and the core module has no knowledge about the patch
module's special sections.
- Newly added kpatch-patch.h defines the format of the patch module
special sections. It's used by create-diff-object to create the
special sections and used by the patch module to read them.
- kpatch.h still defines the core module interfaces. Each kpatch_module
has a list of kpatch_objects for each module object to be patched.
Each kpatch_object has a list of kpatch_funcs and a list of
kpatch_dynrelas. The patch module creates these lists when populating
kpatch_module.
This way of structuring the data allows us to patch funcs and dynrelas
on a per patched object basis, which will allow us to catch more error
scenarios and make the code easier to manage going forward. It also
allows the use of much more common code between kpatch_register() and
kpatch_module_notify().
This adds support to kpatch-build for patching modules. It builds the
entire kernel tree, vmlinux and modules, in a single pass and then
detects which modules need to be patched. This is the easiest case
(since the user doesn't need to care about which binaries are affected)
and the safest (since the user could be wrong).
The first build with no ccache takes a long time, but after the cache is
populated, it only takes about two minutes on my laptop. It does take
up a TON of space in the cache now though (~/.kpatch/obj is now 8GB).
Next we can add the '-t' cmdline option for advanced users to specify
build targets.
Revert the previous kpatch-build module building interface commits to
prepare for a completely different approach which builds vmlinux and all
the modules in a single pass.
This reverts commit fac9d70612.
This reverts commit d166fb4379.
This allows a patch module to contain patched functions for modules
which haven't been loaded yet. If/when the module is loaded later, it
will be patched from the module notifier function.
On Ubuntu, the ccache symlinks aren't automatically added to the PATH,
so update PATH accordingly.
On Fedora, the PATH is updated automatically when installing ccache.
_But_, it requires a new bash session to be created after installing
ccache before the new PATH takes effect. So it's a good idea to fix it
for Fedora as well.
kpatch load fails on Ubuntu with:
kpatch: unable to find module 'vmlinux_3'
The root cause is that the vmlinux file on Ubuntu is named
vmlinux-3.13.0-24-generic instead of just vmlinux.
Let's just call it "vmlinux" in the objname field.
The previous commit did not adjust the indentation to ease with
reviewing. This commit corrects the indentation. Purely whitespace
change.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
This commit adds support for module patching with kpatch-build.
It introduces a new option, -t/--targets, that allows the user to
specify kernel make targets that are impacted by the patch. These
targets will be examined by kpatch-build for changes.
While this approach requires the user to provide more information to
kpatch-build about what exactly has changed, it is better that
rebuilding the entire source tree (make vmlinux && make modules) which
would dramatically increase the runtime and disk space requirements of
using kpatch-build.
Future improvements could include a script that will independently
generate the targets list file.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
With test/integration/data-read-mostly.patch, create-diff-object
includes the __verbose section but not the .rela__verbose section, which
is a bug, resulting in the following printk during the integration
tests:
[13740.801920] dynamic debug error adding module: (null)
If a non-bundled section is included, its rela section should also be
included. Also add support for converting those relas to dynrelas.
When renaming a foo.isra.1 function, there might also be a foo_bar
function which would be falsely matched with the current strchr logic.
Instead of matching the "foo" prefix, match "foo.isra".
This commit adds module patching support to create-diff-object by:
1) generalizing the vmlinux CLI parameter
2) adding the kernel object name to each patch and dynrela
3) adding slightly different logic for vmlinux/module in the dynrela
creation
Signed-off-by: Seth Jennings <sjenning@redhat.com>
Rather than keep the logic in sync between the counting and processing
code in kpatch_create_dynamic_rela_sections() just do a "dumb" count
establishing an upper bound and allocating the buffer, then determine
the actual size (i.e. number of dynrelas) in the processing section.
No functional change intended.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
Make old addresses relative to the start address of the relocatable
kernel or module.
This commit has no functional effect; it just prepares the code for
future acceptance of the module patching support.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
The current approach of trying to include the tracepoint-related
sections doesn't work at all. The new tracepoints don't show up in
"perf list".
And also, with one patch (issue #219) I've seen a panic in
jump_label_del_module(). I suspect it's because the kernel is confused
by dynamic relocations' changing of the jump table after it was
registered with the jump table code.
I think the best approach for now is to just always exclude these
sections. It should be harmless, with the only consequence being that
tracepoints and jump labels can't be enabled in patched functions (which
is already the case with the current code anyway).
Fixes#221.
For a rela with type X86_64_PC32, the addend of the needed symbol is
relative to the address of the instruction _after_ the one which is the
target of the relocation.
We need a disassembler library to help with converting data section
relocation references to their corresponding symbols. Unfortunately,
the only library I could find that's widely available in enterprise
Linux distros was libopcodes, which is part of binutils. But its
interface is far too clunky for our needs.
The best alternative I can find is to just copy the kernel's
disassembler library code from arch/x86/lib.
When a changed function needs relocations for special data sections like
.data..percpu or .data..read_mostly, it's possible for those sections to
get included. We try to avoid that situation by converting section
references to data symbol references in kpatch_replace_sections_syms(),
but the conversion success rate isn't 100%, and we could be forgetting
about some other sections, so ensure that it never happens in
kpatch_verify_patchability().
Abstract out the common functionality for dealing with special sections
into a new kpatch_process_special_sections() function.
The base sections are partitioned into "groups". Only those groups
whose relas reference a changed function are kept. The only difference
in the logic for handling each special section is determining the size
of a given group. Each section has its own group_size() callback for
this. It's a callback instead of an integer because one of the
soon-to-be-supported special sections requires that its group sizes be
dynamically determined.