Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

changed section .rela__jump_table not selected for inclusion #157

Closed
jpoimboe opened this issue Apr 29, 2014 · 2 comments · Fixed by #158
Closed

changed section .rela__jump_table not selected for inclusion #157

jpoimboe opened this issue Apr 29, 2014 · 2 comments · Fixed by #158

Comments

@jpoimboe
Copy link
Member

~ $ cat jumptablefail.patch 
Index: src/kernel/timer.c
===================================================================
--- src.orig/kernel/timer.c
+++ src/kernel/timer.c
@@ -1370,6 +1370,8 @@ static void run_timer_softirq(struct sof
 {
    struct tvec_base *base = __this_cpu_read(tvec_bases);

+   printk("run_timer_softirq\n");
+
    hrtimer_run_pending();

    if (time_after_eq(jiffies, base->timer_jiffies))
~ $ kpatch-build -d jumptablefail.patch
DEBUG mode enabled
Using cache at /home/jpoimboe/.kpatch/3.13.10-200.fc20.x86_64/src
Testing patch file
patching file kernel/timer.c
Building original kernel
Building patched kernel
Detecting changed objects
Rebuilding changed objects
Extracting new and modified ELF sections
timer.o: changed function: run_timer_softirq
timer.o: changed function: timer_cpu_notify
timer.o: changed section .rela__jump_table not selected for inclusion
/usr/local/libexec/kpatch/create-diff-object: unreconcilable difference
ERROR: kpatch build failed. Check /tmp/kpatch-build-1398801879.log for more details.
@jpoimboe
Copy link
Member Author

This is very similar to the .smp_locks issue, except these relocations are 8 bytes:

Relocation section [73] '.rela__jump_table' for section [72] '__jump_table' at offset 0x11bb0 contains 36 entries:
  Offset              Type            Value               Addend Name
  000000000000000000  X86_64_64       000000000000000000     +43 .text.call_timer_fn
  0x0000000000000008  X86_64_64       000000000000000000    +160 .text.call_timer_fn
  0x0000000000000010  X86_64_64       0x0000000000000280      +8 __tracepoint_timer_expire_entry
  0x0000000000000018  X86_64_64       000000000000000000     +54 .text.call_timer_fn
  0x0000000000000020  X86_64_64       000000000000000000    +112 .text.call_timer_fn
  0x0000000000000028  X86_64_64       0x0000000000000240      +8 __tracepoint_timer_expire_exit
  0x0000000000000030  X86_64_64       000000000000000000    +257 .text.run_timer_softirq
  0x0000000000000038  X86_64_64       000000000000000000    +416 .text.run_timer_softirq
  0x0000000000000040  X86_64_64       0x0000000000000200      +8 __tracepoint_timer_cancel
  0x0000000000000048  X86_64_64       000000000000000000     +20 .text.init_timer_key
  0x0000000000000050  X86_64_64       000000000000000000    +112 .text.init_timer_key
  0x0000000000000058  X86_64_64       0x0000000000000300      +8 __tracepoint_timer_init
  0x0000000000000060  X86_64_64       000000000000000000     +35 .text.detach_if_pending
  0x0000000000000068  X86_64_64       000000000000000000    +128 .text.detach_if_pending
  0x0000000000000070  X86_64_64       0x0000000000000200      +8 __tracepoint_timer_cancel
  0x0000000000000078  X86_64_64       000000000000000000     +32 .text.migrate_timer_list
  0x0000000000000080  X86_64_64       000000000000000000    +120 .text.migrate_timer_list
  0x0000000000000088  X86_64_64       0x0000000000000200      +8 __tracepoint_timer_cancel
  0x0000000000000090  X86_64_64       000000000000000000     +80 .sched.text
  0x0000000000000098  X86_64_64       000000000000000000    +440 .sched.text
  0x00000000000000a0  X86_64_64       0x0000000000000300      +8 __tracepoint_timer_init
  0x00000000000000a8  X86_64_64       000000000000000000    +237 .sched.text
  0x00000000000000b0  X86_64_64       000000000000000000    +504 .sched.text
  0x00000000000000b8  X86_64_64       0x00000000000002c0      +8 __tracepoint_timer_start
  0x00000000000000c0  X86_64_64       000000000000000000    +115 .text.add_timer_on
  0x00000000000000c8  X86_64_64       000000000000000000    +176 .text.add_timer_on
  0x00000000000000d0  X86_64_64       0x00000000000002c0      +8 __tracepoint_timer_start
  0x00000000000000d8  X86_64_64       000000000000000000     +95 .text.mod_timer_pinned
  0x00000000000000e0  X86_64_64       000000000000000000    +232 .text.mod_timer_pinned
  0x00000000000000e8  X86_64_64       0x00000000000002c0      +8 __tracepoint_timer_start
  0x00000000000000f0  X86_64_64       000000000000000000    +128 .text.mod_timer_pending
  0x00000000000000f8  X86_64_64       000000000000000000    +256 .text.mod_timer_pending
  0x0000000000000100  X86_64_64       0x00000000000002c0      +8 __tracepoint_timer_start
  0x0000000000000108  X86_64_64       000000000000000000    +136 .text.mod_timer
  0x0000000000000110  X86_64_64       000000000000000000    +144 .text.mod_timer
  0x0000000000000118  X86_64_64       0x00000000000002c0      +8 __tracepoint_timer_start

jpoimboe added a commit to jpoimboe/kpatch that referenced this issue Apr 29, 2014
Almost a line-for-line copy/paste of the smp locks function.  The only
differences are the section name, and an offset increment of 8 instead
of 4.

Fixes dynup#157.
@sjenning sjenning reopened this Apr 30, 2014
@sjenning
Copy link
Contributor

Revised analysis:

__jump_table is a table of struct jump_entry, 24 bytes in size on x86_64, init'ed to 0. All three fields are reloc'ed.

from arch/x86/include/asm/jump_label.h

#ifdef CONFIG_X86_64
typedef u64 jump_label_t;
#else
typedef u32 jump_label_t;
#endif

struct jump_entry {
    jump_label_t code;
    jump_label_t target;
    jump_label_t key;
};

.rela__jump_table looks like this:

Relocation section [73] '.rela__jump_table' for section [72] '__jump_table' at offset 0x11bb0 contains 36 entries:
  Offset              Type            Value               Addend Name
  000000000000000000  X86_64_64       000000000000000000     +43 .text.call_timer_fn
  0x0000000000000008  X86_64_64       000000000000000000    +160 .text.call_timer_fn
  0x0000000000000010  X86_64_64       0x0000000000000280      +8 __tracepoint_timer_expire_entry

The "code" and "target" fields point to locations within the function with the tracepoint. The "key" field points to a symbol "__tracepoint_timer_expire_entry" which references the __tracepoints section. There is a _tracepoint* symbol for each tracepoint in the __tracepoints section.

The __tracepoints section, in turn, is a table of struct tracepoints, 64 bytes in size on x86_64, init'ed to 0.

from include/linux/tracepoint.h

struct tracepoint {
    const char *name;       /* Tracepoint name */
    struct static_key key;
    void (*regfunc)(void);
    void (*unregfunc)(void);
    struct tracepoint_func __rcu *funcs;
};

The "name" field is reloc'ed, referencing an offset in a string table contained in the __tracepoints_strings section:

Relocation section [288] '.rela__tracepoints' for section [287] '__tracepoints' at offset 0x14f88 contains 13 entries:
  Offset              Type            Value               Addend Name
  000000000000000000  X86_64_64       000000000000000000      +0 __tracepoints_strings
  0x0000000000000040  X86_64_64       000000000000000000     +10 __tracepoints_strings
  0x0000000000000080  X86_64_64       000000000000000000     +24 __tracepoints_strings
...

There are _tpstrtab* symbols pointing to each string in the string in the table.

Additionally there is a __tracepoints_ptrs section that is a table of pointers that reference the struct tracepoints in the __tracepoints section. There are also _tracepoint_ptr* symbols that reference the pointers in __tracepoint_ptrs.

So... this rabbit hole goes much deeper than originally thought.

jpoimboe added a commit to jpoimboe/kpatch that referenced this issue May 27, 2014
Add support for the following special sections:

- __jump_table
- __tracepoints
- __tracepoints_ptrs
- __tracepoints_strings

Fixes dynup#157.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants