dynup / kpatch

kpatch - live kernel patching
GNU General Public License v2.0
1.49k stars 305 forks source link

find_local_syms: 218: couldn't find matching cm.c local symbols in ib_mad symbol table #1402

Closed wardenjohn closed 4 weeks ago

wardenjohn commented 2 months ago

Background: ib_mad is the result ko which is linked to cm.o by ld. This is a oot-module driver which is not a part of kernel.

Please point me out if you find any wrong of my description or in my understanding. Thank you very much!

When I build a kpatch, I found that find_local_syms raised an error in lookup.c

Because there can be duplicate symbols and duplicate filenames we need to correlate each symbol from the elf file to it's corresponding symbol in lookup table. Both the elf file and the lookup table can be split on STT_FILE symbols into blocks of symbols originating from a single source file. We then compare local symbol lists from both blocks and store the pointer to STT_FILE symbol in lookup table for later use in lookup_local_symbol().

I read this comment in lookup.c, may be not understand this comment very well.

list_for_each_entry(sym, &kelf->symbols, list) {
        if (sym->type == STT_FILE)
            find_local_syms(table, sym, &kelf->symbols);
}

table : The symbol table structer contains module symbol list and the Module export symbol list. sym : In this case, this is a struct symbol of cm.c because this sym->type is STT_FILE kelf->symbols: all the symbol of the orig.o

this code shows me that for the orig.o, if I found a symbol type is STT_FILE, we should look into the symbol.

When I look into the function of find_local_syms, I have some questions:

  1. In the first loop, we scan all the symbol in lookup_table (lookup_table contains all the symbol from model's symtab and Module.symver), if we found a symbol in the lookup_table that : (1) this is a STT_FILE type; (2): locals_match; that mean we have got a lookup_table_file_syms. My question is : what is the meaning of locals_match function?
  2. Why we have to find a matching local symbol if the module symbol table?
  3. Actually, I dont really understand what find_local_syms_multiple do (may be my knowledge of elf file is not enough...lol), which make me unable to solve this problem or even understand it.

That's why I come here for help. Thanks!

Hope to hear from you ! Your Sincerely!

wardenjohn commented 2 months ago

Oh , yeah. More information I shoud provide!

The create_diff_object is:

/usr/local/libexec/kpatch/create-diff-object  orig/drivers/infiniband/core/cm.o patched/drivers/infiniband/core/cm.o ib_mad /root/.kpatch/tmp/module/ib_mad.symtab /root/.kpatch/tmp/Module.symvers kpatch_IB_CM_MRA_REP_RCVD output/drivers/infiniband/core/cm.o

and there are only tow FILE TYPE symbols in the ib_mad.symtab is like following:

FILE    LOCAL  DEFAULT  ABS ib_mad_dummy.c
FILE    LOCAL  DEFAULT  ABS ib_mad.mod.c
wardenjohn commented 2 months ago

Oh, I seem to get some point.

It seems that we are going patch the final module ib_mad. To patch this module, we should make sure that there is a relationship between ib_mad and cm.o. The symbol table of cm.o show us this object is from cm.c source file.

To patch ib_mad, we should make sure the function if ib_mad is also exist in cm.c file because the changed object now is cm.o. So, we have to check the symtab of ib_mad (ib_mad.symtab) to make sure cm.c is one of its source.

=========== Let's disucess kernel kpatch.

In kernel kpatch. We are going to patch vmlinux.

If we make changes to A.o and B.o, we must make sure A.c and B.c is one of the source of vmlinux (because the object we going to patch is vmlinux). That's why we need to check if A.c and B.c File symbol existed in vmlinx.symtab

Is my understanding right?

joe-lawrence commented 2 months ago

Without doing a deep dive on this code, IIRC the idea is that we should see similar symbol table listings for file foo.c in both the target build (vmlinux or module.ko) and the kpatch-build created "original" build (vmlinux or module.ko but with -ffunction-sections, -fdata-sections).

Errors like $SUBJECT usually occur when there is some toolchain differences (target vs. kpatch-build invoked) or the presence of so-called discarded symbol that kpatch-build hasn't yet accounted for ("__pfx" symbols maybe) in the pre-linked object files.

Can you post/attach /root/.kpatch/tmp/module/ib_mad.symtab and the result of readelf --wide --symbols orig/drivers/infiniband/core/cm.o?

wardenjohn commented 2 months ago

@joe-lawrence Hi bro!

I think I may find it out.

the ib_mad.symtab contains the symbols from ib_mad.o, this symbol table contains the symbol of functions and the source file of this object.

And find local syms should make sure that the symbol from cm.o should exactly exist in the patching target. Otherwaise, if we are going to patch the target, the missing target may cause problem. That's why find_locals_match exist (am I understand right?). That's the symbol of ib_mad: image

I readelf -s cm.o found the symbol in cm.o is not exist in the ib_mad

joe-lawrence commented 2 months ago

And find local syms should make sure that the symbol from cm.o should exactly exist in the patching target. Otherwaise, if we are going to patch the target, the missing target may cause problem. That's why find_locals_match exist (am I understand right?).

Right, that is my understanding (save for any "discarded" symbols that may be found in the object file, but not the target, as they may be dropped at link time (see maybe_discarded_sym() for examples)).

github-actions[bot] commented 1 month ago

This issue has been open for 30 days with no activity and no assignee. It will be closed in 7 days unless a comment is added.

github-actions[bot] commented 4 weeks ago

This issue was closed because it was inactive for 7 days after being marked stale.