Allow correlating original locals to patched globals, and vice versa.
This is needed when:

1. User adds/removes "static" for a function.
2. CONFIG_LTO_CLANG_THIN promotes local functions and objects to global
   and add .llvm.<hash> suffix.

Given this is a less common scenario, show warnings when this is needed.

Signed-off-by: Song Liu <[email protected]>
---
 tools/objtool/klp-diff.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index 147e7e7176fb..07fcaca46160 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -519,6 +519,37 @@ static int correlate_symbols(struct elfs *e)
                }
        }
 
+       /* Correlate original locals with patched globals */
+       for_each_sym(e->orig, sym1) {
+               if (sym1->twin || dont_correlate(sym1) || !is_local_sym(sym1))
+                       continue;
+               sym2 = find_global_symbol_by_name(e->patched, sym1->name);
+               if (!sym2 && find_global_symbol_by_demangled_name(e->patched, 
sym1, &sym2))
+                       return -1;
+               if (sym2 && !sym2->twin) {
+                       sym1->twin = sym2;
+                       sym2->twin = sym1;
+                       WARN("correlate LOCAL %s (original) to GLOBAL %s 
(patched)",
+                            sym1->name, sym2->name);
+               }
+       }
+
+       /* Correlate original globals with patched locals */
+       for_each_sym(e->patched, sym2) {
+               if (sym2->twin || dont_correlate(sym2) || !is_local_sym(sym2))
+                       continue;
+               sym1 = find_global_symbol_by_name(e->orig, sym2->name);
+               if (!sym1 && find_global_symbol_by_demangled_name(e->patched, 
sym2, &sym1))
+                       return -1;
+
+               if (sym1 && !sym1->twin) {
+                       sym2->twin = sym1;
+                       sym1->twin = sym2;
+                       WARN("correlate GLOBAL %s (origial) to LOCAL %s 
(patched)",
+                            sym1->name, sym2->name);
+               }
+       }
+
        for_each_sym(e->orig, sym1) {
                if (sym1->twin || dont_correlate(sym1))
                        continue;
-- 
2.47.3


Reply via email to