With #650, we found that using -ffunction-sections and -fdata-sections
sometimes causes GCC to output the local symbols in a different order in
the symbol table. So don't assume they're in the same order, and
instead search all the locals.
This requires two passes: once going through the lookup table symbols
and once going through the .o symbols. This is needed to make sure
there aren't any extra symbols in one of the files.
I also reorganized the code a bit to simplify it.
When compiling with -O2, it fails with:
gcc -MMD -MP -O2 -I../kmod/patch -Iinsn -Wall -g -Werror -c -o lookup.o lookup.c
lookup.c: In function ‘lookup_open’:
lookup.c:132:21: error: ‘file_sym’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
table->local_syms = file_sym;
~~~~~~~~~~~~~~~~~~^~~~~~~~~~
lookup.c:83:30: note: ‘file_sym’ was declared here
struct object_symbol *sym, *file_sym;
^~~~~~~~
lookup.c:129:27: error: ‘child_sym’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
if (in_file && !child_sym->name) {
~~~~~~~~~^~~~~~
lookup.c:85:27: note: ‘child_sym’ was declared here
struct sym_compare_type *child_sym;
^~~~~~~~~
cc1: all warnings being treated as errors
Makefile:17: recipe for target 'lookup.o' failed
make[1]: *** [lookup.o] Error 1
make[1]: Leaving directory '/home/jpoimboe/git/kpatch/kpatch-build'
Makefile:14: recipe for target 'build-kpatch-build' failed
make: *** [build-kpatch-build] Error 2
As far as I can tell, these are false positive warnings. When in_file
is 1, file_sym and child_sym are properly initialized. But silence the
warnings anyway so Gentoo users can build with -O2.
Fixes: #675
On Debian/Ubuntu, the `vmlinux` from `-dbg` package has a version number
appended to it. For example:
`/usr/lib/debug/boot/vmlinux-3.13.0-117-generic`. Make it work
nonetheless.
A couple of minor cleanups:
- move the `if (locals)` check to find_local_syms()
- remove the explicit initialization of `local_syms`, the entire struct
was already previously cleared to zero.
A few symbols are discarded in the kernel linking phase, which means
they won't be in the lookup table. Skip their comparison.
This fixes a bunch of warnings seen when building a patch which triggers
a tree-wide rebuild:
create-diff-object: ERROR: aes_glue.o: find_local_syms: 112: find_local_syms for aes_glue.c: found_none
create-diff-object: ERROR: aesni-intel_glue.o: find_local_syms: 112: find_local_syms for aesni-intel_glue.c: found_none
create-diff-object: ERROR: init.o: find_local_syms: 112: find_local_syms for init.c: found_none
create-diff-object: ERROR: iosf_mbi.o: find_local_syms: 112: find_local_syms for iosf_mbi.c: found_none
create-diff-object: ERROR: setup.o: find_local_syms: 112: find_local_syms for setup.c: found_none
...
After this patch, there's still one warning remaining:
create-diff-object: ERROR: dynamic_debug.o: find_local_syms: 133: find_local_syms for dynamic_debug.c: found_none
That one has a completely different cause, which I'll fix in another
pull request (coming soon).
Fixes: #676
Rename a couple of the variables in find_local_syms() to better reflect
their purpose. The passed in 'locals' are from the childobj (e.g.
foo.o) rather than the parent (e.g. vmlinux).
We use kelf_base->symbols to find a unique matching FILE+locals combination
when we call lookup_open(). If we can't find one matching or we find more
than one matching, we error out.
If we find a unique one, we setup table->local_syms in lookup_open(),
so later lookup_local_symbol() could do its lookup based on table->local_syms.
Fixes#604.
Suggested-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Zhou Chengming <zhouchengming1@huawei.com>
Have lookup_open() also parse Module.symvers and add the resulting symbols
and their objnames to the lookup table. This code was essentially
cherry-picked from Josh Poimboeuf's lookup code found here:
8cdca59c88
That patch was modified to fix a bug in obj_read() (calling elf_end()
without strdup'ing the symbol name strings, which was causing null
dereferences) and to fix up the module name after reading it from
Module.symvers (replacing '-' with '_' and stripping the path prefixes).
Also, add lookup_exported_symbol_objname(), which looks up the objname of
an exported symbol by making use of the objname information obtained from
Module.symvers.
Give a slightly better error message for the dup file+symbol issue.
It's still cryptic but it's good enough to at least give us kpatch
developers a better idea about what went wrong. This would have helped
diagnose issue #633 much more quickly.
Support patching objects that have duplicated function names. This feature was
introduced upstream in Linux v4.5.
This patch appends the symbol position to the symbol structure when
lookup_local_symbol is called. This pos variable is then used when creating the
funcs and dynrelas sections. Finally, incorporate sympos into the livepatch
patch hook only if the kernel version is greater than v4.5. In other cases the
older format is used.
Fixes: #493
Signed-off-by: Chris J Arges <chris.j.arges@canonical.com>
Before this patch, if changed function is weak symbol, it is not
be allowed to create live patch, and it will trigger the following
error:
/usr/local/libexec/kpatch/create-diff-object: ERROR: ***.o:
kpatch_create_patches_sections: 2294: lookup_global_symbol ***
And if the changed function reference the weak symbol, when loading
the patch module will trigger the following error:
module kpatch-***: overflow in relocation type *** val 0
insmod: can't insert 'kpatch-***.ko': invalid module format
This patch fix it and add support for patching weak function.
Signed-off-by: Li Bin <huawei.libin@huawei.com>
In preparation for dynamic symbol linking, the symbol lookup logic
is going to move into create-diff-obj anyway. We might as well
minimize the code duplication and pull this into create-diff-obj.
This avoids having to re-parse the ELF file modify it in-place.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
Conflicts:
kpatch-build/kpatch-build
We merged PR #186 a little too hastily. It seg faults with the new
parainstructions-section.patch in the integration test suite. Reverting
it for now until we get it figured out.
This reverts commit e1177e3a03.
This reverts commit 880e271841.
This reverts commit 2de5f6cbfb.
This reverts commit 38b7ac74ad.
This reverts commit 108cd9f95e.
In preparation for dynamic symbol linking, the symbol lookup logic
is going to move into create-diff-obj anyway. We might as well
minimize the code duplication and pull this into create-diff-obj.
This avoids having to re-parse the ELF file modify it in-place.
Signed-off-by: Seth Jennings <sjenning@redhat.com>