kpatch/kmod/core/kpatch.h
Josh Poimboeuf 34cc258a31 fix undefined symbols for future loaded modules
When patching module A, if one of the new function's relas reference a
symbol in module B, we currently just leave it as a normal rela.  But if
module B hasn't been loaded yet, the patch module will fail to load due
to the rela's reference to an undefined symbol.

The fix is to convert these relas to dynrelas, which can be resolved
later in the module notifier when A is loaded.

Also added support for the R_X86_64_NONE relocation type, needed for
dynrelas which reference __fentry__.
2014-06-18 11:17:11 -05:00

89 lines
2.0 KiB
C

/*
* kpatch.h
*
* Copyright (C) 2014 Seth Jennings <sjenning@redhat.com>
* Copyright (C) 2013-2014 Josh Poimboeuf <jpoimboe@redhat.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>.
*
* Contains the API for the core kpatch module used by the patch modules
*/
#ifndef _KPATCH_H_
#define _KPATCH_H_
#include <linux/types.h>
#include <linux/module.h>
enum kpatch_op {
KPATCH_OP_NONE,
KPATCH_OP_PATCH,
KPATCH_OP_UNPATCH,
};
struct kpatch_func {
/* public */
unsigned long new_addr;
unsigned long new_size;
unsigned long old_offset;
unsigned long old_size;
const char *name;
struct list_head list;
/* private */
struct hlist_node node;
unsigned long old_addr;
enum kpatch_op op;
};
struct kpatch_dynrela {
unsigned long dest;
unsigned long src;
unsigned long type;
const char *name;
const char *objname;
int addend;
bool exported;
struct list_head list;
};
struct kpatch_object {
struct list_head list;
const char *name;
struct list_head funcs;
struct list_head dynrelas;
/* private */
struct module *mod;
};
struct kpatch_module {
/* public */
struct module *mod;
struct list_head objects;
/* public read-only */
bool enabled;
/* private */
struct list_head list;
};
extern struct kobject *kpatch_patches_kobj;
extern int kpatch_register(struct kpatch_module *kpmod, bool replace);
extern int kpatch_unregister(struct kpatch_module *kpmod);
#endif /* _KPATCH_H_ */