Merge branches 'for-4.7/core', 'for-4.7/livepatching-doc' and 'for-4.7/livepatching...
authorJiri Kosina <jkosina@suse.cz>
Tue, 17 May 2016 10:06:35 +0000 (12:06 +0200)
committerJiri Kosina <jkosina@suse.cz>
Tue, 17 May 2016 10:06:35 +0000 (12:06 +0200)
1  2  3 
include/linux/livepatch.h
kernel/livepatch/core.c

Simple merge
index ddef649a29147ccb3399d484a687f763afb0aeb5,d68fbf63b0836737977882f1874c02c8cf8504d7,a19f1954f4ac7c1f9fde0af0bc0905547b4a8aef..5c2bc1052691dba60b9285f69b8536595e1dfb36
@@@@ -240,39 -240,39 -272,43 +272,43 @@@@ static int klp_write_object_relocations
        if (WARN_ON(!klp_is_object_loaded(obj)))
                return -EINVAL;
   
--      if (WARN_ON(!obj->relocs))
--              return -EINVAL;
++      objname = klp_is_module(obj) ? obj->name : "vmlinux";
   
        module_disable_ro(pmod);
-       for (reloc = obj->relocs; reloc->name; reloc++) {
-               /* discover the address of the referenced symbol */
-               if (reloc->external) {
-                       if (reloc->sympos > 0) {
-                               pr_err("non-zero sympos for external reloc symbol '%s' is not supported\n",
-                                      reloc->name);
-                               ret = -EINVAL;
-                               goto out;
-                       }
-                       ret = klp_find_external_symbol(pmod, reloc->name, &val);
-               } else
-                       ret = klp_find_object_symbol(obj->name,
-                                                    reloc->name,
-                                                    reloc->sympos,
-                                                    &val);
++      /* For each klp relocation section */
++      for (i = 1; i < pmod->klp_info->hdr.e_shnum; i++) {
++              sec = pmod->klp_info->sechdrs + i;
++              secname = pmod->klp_info->secstrings + sec->sh_name;
++              if (!(sec->sh_flags & SHF_RELA_LIVEPATCH))
++                      continue;
 + 
 -      for (reloc = obj->relocs; reloc->name; reloc++) {
 -              /* discover the address of the referenced symbol */
 -              if (reloc->external) {
 -                      if (reloc->sympos > 0) {
 -                              pr_err("non-zero sympos for external reloc symbol '%s' is not supported\n",
 -                                     reloc->name);
 -                              ret = -EINVAL;
 -                              goto out;
 -                      }
 -                      ret = klp_find_external_symbol(pmod, reloc->name, &val);
 -              } else
 -                      ret = klp_find_object_symbol(obj->name,
 -                                                   reloc->name,
 -                                                   reloc->sympos,
 -                                                   &val);
++              /*
++               * Format: .klp.rela.sec_objname.section_name
++               * See comment in klp_resolve_symbols() for an explanation
++               * of the selected field width value.
++               */
++              cnt = sscanf(secname, ".klp.rela.%55[^.]", sec_objname);
++              if (cnt != 1) {
++                      pr_err("section %s has an incorrectly formatted name",
++                             secname);
++                      ret = -EINVAL;
++                      break;
++              }
+  
++              if (strcmp(objname, sec_objname))
++                      continue;
++ 
++              ret = klp_resolve_symbols(sec, pmod);
                if (ret)
--                      goto out;
++                      break;
   
--              ret = klp_write_module_reloc(pmod, reloc->type, reloc->loc,
--                                           val + reloc->addend);
--              if (ret) {
--                      pr_err("relocation failed for symbol '%s' at 0x%016lx (%d)\n",
--                             reloc->name, val, ret);
--                      goto out;
--              }
++              ret = apply_relocate_add(pmod->klp_info->sechdrs,
++                                       pmod->core_kallsyms.strtab,
++                                       pmod->klp_info->symndx, i, pmod);
++              if (ret)
++                      break;
        }
   
-- out:
        module_enable_ro(pmod);
        return ret;
   }