Blame kpatch-build/kpatch-elf.h

Packit c71e3f
/*
Packit c71e3f
 * kpatch-elf.h
Packit c71e3f
 *
Packit c71e3f
 * This program is free software; you can redistribute it and/or
Packit c71e3f
 * modify it under the terms of the GNU General Public License
Packit c71e3f
 * as published by the Free Software Foundation; either version 2
Packit c71e3f
 * of the License, or (at your option) any later version.
Packit c71e3f
 *
Packit c71e3f
 * This program is distributed in the hope that it will be useful,
Packit c71e3f
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit c71e3f
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit c71e3f
 * GNU General Public License for more details.
Packit c71e3f
 *
Packit c71e3f
 * You should have received a copy of the GNU General Public License
Packit c71e3f
 * along with this program; if not, write to the Free Software
Packit c71e3f
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA,
Packit c71e3f
 * 02110-1301, USA.
Packit c71e3f
 */
Packit c71e3f
Packit c71e3f
#ifndef _KPATCH_ELF_H_
Packit c71e3f
#define _KPATCH_ELF_H_
Packit c71e3f
Packit c71e3f
#include <stdbool.h>
Packit c71e3f
#include <gelf.h>
Packit c71e3f
#include "list.h"
Packit c71e3f
#include "log.h"
Packit c71e3f
Packit c71e3f
#define KLP_SYM_PREFIX		".klp.sym."
Packit c71e3f
#define KLP_RELASEC_PREFIX	".klp.rela."
Packit c71e3f
#define KLP_ARCH_PREFIX 	".klp.arch."
Packit c71e3f
#define SHF_RELA_LIVEPATCH	0x00100000
Packit c71e3f
#define SHN_LIVEPATCH		0xff20
Packit c71e3f
Packit c71e3f
/*******************
Packit c71e3f
 * Data structures
Packit c71e3f
 * ****************/
Packit c71e3f
struct section;
Packit c71e3f
struct symbol;
Packit c71e3f
struct rela;
Packit c71e3f
Packit c71e3f
enum status {
Packit c71e3f
	NEW,
Packit c71e3f
	CHANGED,
Packit c71e3f
	SAME
Packit c71e3f
};
Packit c71e3f
Packit c71e3f
struct section {
Packit c71e3f
	struct list_head list;
Packit c71e3f
	struct section *twin;
Packit c71e3f
	GElf_Shdr sh;
Packit c71e3f
	Elf_Data *data;
Packit c71e3f
	char *name;
Packit c71e3f
	unsigned int index;
Packit c71e3f
	enum status status;
Packit c71e3f
	int include;
Packit c71e3f
	int ignore;
Packit c71e3f
	int grouped;
Packit c71e3f
	union {
Packit c71e3f
		struct { /* if (is_rela_section()) */
Packit c71e3f
			struct section *base;
Packit c71e3f
			struct list_head relas;
Packit c71e3f
		};
Packit c71e3f
		struct { /* else */
Packit c71e3f
			struct section *rela;
Packit c71e3f
			struct symbol *secsym, *sym;
Packit c71e3f
		};
Packit c71e3f
	};
Packit c71e3f
};
Packit c71e3f
Packit c71e3f
struct symbol {
Packit c71e3f
	struct list_head list;
Packit c71e3f
	struct symbol *twin;
Packit c71e3f
	struct section *sec;
Packit c71e3f
	GElf_Sym sym;
Packit c71e3f
	char *name;
Packit c71e3f
	unsigned int index;
Packit c71e3f
	unsigned char bind, type;
Packit c71e3f
	enum status status;
Packit c71e3f
	union {
Packit c71e3f
		int include; /* used in the patched elf */
Packit c71e3f
		int strip; /* used in the output elf */
Packit c71e3f
	};
Packit c71e3f
	int has_func_profiling;
Packit c71e3f
};
Packit c71e3f
Packit c71e3f
struct rela {
Packit c71e3f
	struct list_head list;
Packit c71e3f
	GElf_Rela rela;
Packit c71e3f
	struct symbol *sym;
Packit c71e3f
	unsigned int type;
Packit c71e3f
	int addend;
Packit c71e3f
	unsigned int offset;
Packit c71e3f
	char *string;
Packit c71e3f
	bool need_dynrela;
Packit c71e3f
};
Packit c71e3f
Packit c71e3f
struct string {
Packit c71e3f
	struct list_head list;
Packit c71e3f
	char *name;
Packit c71e3f
};
Packit c71e3f
Packit c71e3f
struct kpatch_elf {
Packit c71e3f
	Elf *elf;
Packit c71e3f
	struct list_head sections;
Packit c71e3f
	struct list_head symbols;
Packit c71e3f
	struct list_head strings;
Packit c71e3f
	int fd;
Packit c71e3f
};
Packit c71e3f
Packit c71e3f
/*******************
Packit c71e3f
 * Helper functions
Packit c71e3f
 ******************/
Packit c71e3f
char *status_str(enum status status);
Packit c71e3f
int is_rela_section(struct section *sec);
Packit c71e3f
int is_text_section(struct section *sec);
Packit c71e3f
int is_debug_section(struct section *sec);
Packit c71e3f
Packit c71e3f
struct section *find_section_by_index(struct list_head *list, unsigned int index);
Packit c71e3f
struct section *find_section_by_name(struct list_head *list, const char *name);
Packit c71e3f
struct symbol *find_symbol_by_index(struct list_head *list, size_t index);
Packit c71e3f
struct symbol *find_symbol_by_name(struct list_head *list, const char *name);
Packit c71e3f
struct rela *find_rela_by_offset(struct section *relasec, unsigned int offset);
Packit c71e3f
Packit c71e3f
#define ALLOC_LINK(_new, _list) \
Packit c71e3f
{ \
Packit c71e3f
	(_new) = malloc(sizeof(*(_new))); \
Packit c71e3f
	if (!(_new)) \
Packit c71e3f
		ERROR("malloc"); \
Packit c71e3f
	memset((_new), 0, sizeof(*(_new))); \
Packit c71e3f
	INIT_LIST_HEAD(&(_new)->list); \
Packit c71e3f
	if (_list) \
Packit c71e3f
		list_add_tail(&(_new)->list, (_list)); \
Packit c71e3f
}
Packit c71e3f
Packit c71e3f
int offset_of_string(struct list_head *list, char *name);
Packit c71e3f
Packit c71e3f
#ifndef R_PPC64_ENTRY
Packit c71e3f
#define R_PPC64_ENTRY   118
Packit c71e3f
#endif
Packit c71e3f
Packit c71e3f
/*************
Packit c71e3f
 * Functions
Packit c71e3f
 * **********/
Packit c71e3f
void kpatch_create_rela_list(struct kpatch_elf *kelf, struct section *sec);
Packit c71e3f
void kpatch_create_section_list(struct kpatch_elf *kelf);
Packit c71e3f
void kpatch_create_symbol_list(struct kpatch_elf *kelf);
Packit c71e3f
struct kpatch_elf *kpatch_elf_open(const char *name);
Packit c71e3f
void kpatch_dump_kelf(struct kpatch_elf *kelf);
Packit c71e3f
Packit c71e3f
int is_null_sym(struct symbol *sym);
Packit c71e3f
int is_file_sym(struct symbol *sym);
Packit c71e3f
int is_local_func_sym(struct symbol *sym);
Packit c71e3f
int is_local_sym(struct symbol *sym);
Packit c71e3f
Packit c71e3f
void print_strtab(char *buf, size_t size);
Packit c71e3f
void kpatch_create_shstrtab(struct kpatch_elf *kelf);
Packit c71e3f
void kpatch_create_strtab(struct kpatch_elf *kelf);
Packit c71e3f
void kpatch_create_symtab(struct kpatch_elf *kelf);
Packit c71e3f
struct section *create_section_pair(struct kpatch_elf *kelf, char *name,
Packit c71e3f
                                    int entsize, int nr);
Packit c71e3f
void kpatch_remove_and_free_section(struct kpatch_elf *kelf, char *secname);
Packit c71e3f
void kpatch_reindex_elements(struct kpatch_elf *kelf);
Packit c71e3f
void kpatch_rebuild_rela_section_data(struct section *sec);
Packit c71e3f
void kpatch_write_output_elf(struct kpatch_elf *kelf, Elf *elf, char *outfile);
Packit c71e3f
void kpatch_elf_teardown(struct kpatch_elf *kelf);
Packit c71e3f
void kpatch_elf_free(struct kpatch_elf *kelf);
Packit c71e3f
#endif /* _KPATCH_ELF_H_ */