Changes to special sections are not accounted for right now.  For example a
change that only affects .altinstructions or .ex_table won't be included in the
livepatch payload, if none of the symbols referenced by those sections have
also changed.

Since it's not possible to know which elements in the special group have
changed if we detect a change in the special section the whole group (minus
elements that have references to init section symbols) must be included.

Signed-off-by: Roger Pau Monné <roger....@citrix.com>
---
 create-diff-object.c | 33 ++++++++++++++++++++++++++-------
 1 file changed, 26 insertions(+), 7 deletions(-)

diff --git a/create-diff-object.c b/create-diff-object.c
index d1b1477be1cd..8bfb6bf92a1b 100644
--- a/create-diff-object.c
+++ b/create-diff-object.c
@@ -1170,13 +1170,32 @@ static int should_keep_rela_group(struct section *sec, 
int start, int size)
         */
        list_for_each_entry(rela, &sec->relas, list) {
                if (rela->offset >= start &&
-                   rela->offset < start + size &&
-                   (rela->sym->type == STT_FUNC ||
-                    rela->sym->type == STT_SECTION) &&
-                   rela->sym->sec->include) {
-                       found = 1;
-                       log_debug("new/changed symbol %s found in special 
section %s\n",
-                                 rela->sym->name, sec->name);
+                   rela->offset < start + size)
+               {
+                       /*
+                        * Avoid including groups with relocations against
+                        * symbols living in init sections, those are never
+                        * included in livepatches.
+                        */
+                       if (is_init_section(rela->sym->sec))
+                               return 0;
+
+                       /*
+                        * If the base section has changed, always include all
+                        * groups (except those pointing to .init section
+                        * symbols), as we have no way to differentiate which
+                        * groups have changed.
+                        */
+                       if (sec->status != SAME || sec->base->status != SAME)
+                               found = 1;
+                       else if ((rela->sym->type == STT_FUNC ||
+                                 rela->sym->type == STT_SECTION) &&
+                                rela->sym->sec->include) {
+                               found = 1;
+                               log_debug(
+               "new/changed symbol %s found in special section %s\n",
+                                         rela->sym->name, sec->name);
+                       }
                }
        }
 
-- 
2.44.0


Reply via email to