diff --git a/src/arch/aarch64/arch_parse.c b/src/arch/aarch64/arch_parse.c index f91ef0cf2fbb4e44f56a15693a7f27585532b477..8e01e157a4ec800463e659563d66b7f8b21810e3 100644 --- a/src/arch/aarch64/arch_parse.c +++ b/src/arch/aarch64/arch_parse.c @@ -7,6 +7,9 @@ * * 2021.09.23 - arch/aarch64/arch_parse: modify is_variable_start function for gensrc in arm * Huawei Technologies Co., Ltd. + + * 2022.02.11 - arch/aarch64/arch_parse: fix add new global var bug + * China Telecom ******************************************************************************/ #include @@ -15,7 +18,7 @@ #include "include/kpatch_parse.h" #include "include/kpatch_flags.h" -int is_function_start(struct kp_file *f, int l, kpstr_t *nm) +int is_function_start(struct kpg_file *f, int l, kpstr_t *nm) { char *s; kpstr_t nm2, attr; @@ -112,7 +115,7 @@ int is_data_def(char *s, int type) return 0; } -int is_variable_start(struct kp_file *f, int l, int *e, int *pglobl, kpstr_t *nm) +int is_variable_start(struct kpg_file *f, int l, int *e, int *pglobl, kpstr_t *nm) { char *s; int l0 = l, globl = 0; @@ -191,7 +194,7 @@ int is_variable_start(struct kp_file *f, int l, int *e, int *pglobl, kpstr_t *nm } /* break manually crafted multiple statements separated by ; to separate lines */ -void init_multilines(struct kp_file *f) +void init_multilines(struct kpg_file *f) { int i, nr, sz = 64, slen, first_token; char **lines = NULL, *s, *se; diff --git a/src/arch/x86/arch_parse.c b/src/arch/x86/arch_parse.c index 15cf9fe758a7a194c2b48d4c5e4703b24f0658f0..e0761a3260924de743d97ee77abc62364f9edeaa 100644 --- a/src/arch/x86/arch_parse.c +++ b/src/arch/x86/arch_parse.c @@ -1,6 +1,9 @@ /****************************************************************************** * 2021.10.08 - enhance kpatch_gensrc and kpatch_elf and kpatch_cc code * Huawei Technologies Co., Ltd. + * + * 2022.02.11 - arch/x86/arch_parse: fix add new global var bug + * China Telecom ******************************************************************************/ #include @@ -9,7 +12,7 @@ #include "include/kpatch_parse.h" #include "include/kpatch_flags.h" -int is_function_start(struct kp_file *f, int l, kpstr_t *nm) +int is_function_start(struct kpp_file *f, int l, kpstr_t *nm) { char *s; kpstr_t nm2, attr; @@ -76,7 +79,7 @@ int is_data_def(char *s, int type) return 0; } -int is_variable_start(struct kp_file *f, int l, int *e, int *pglobl, kpstr_t *nm) +int is_variable_start(struct kpp_file *f, int l, int *e, int *pglobl, kpstr_t *nm) { char *s; int l0 = l, globl = 0; @@ -147,7 +150,7 @@ int is_variable_start(struct kp_file *f, int l, int *e, int *pglobl, kpstr_t *nm } /* break manually crafted multiple statements separated by ; to separate lines */ -void init_multilines(struct kp_file *f) +void init_multilines(struct kpp_file *f) { int i, nr, sz = 64, slen, first_token; char **lines = NULL, *s, *se; diff --git a/src/include/kpatch_dbgfilter.h b/src/include/kpatch_dbgfilter.h index ab7dfb5b0eaee54e66d40fb43935c47991f9cb2d..87f1b8089423077d120731d06ad040c64ed7bc80 100644 --- a/src/include/kpatch_dbgfilter.h +++ b/src/include/kpatch_dbgfilter.h @@ -8,6 +8,6 @@ #define DFO_SKIP_CFI 1 << 2 #define DFO_EMIT_NEWLINES 1 << 3 -void debug_filter(struct kp_file *fin, struct kp_file *fout, int options); +void debug_filter(struct kpg_file *fin, struct kpg_file *fout, int options); #endif /* __DBGFILTER_H__ */ diff --git a/src/include/kpatch_io.h b/src/include/kpatch_io.h index 7936c8937b4b664e3a195c6e541c4428ca9be886..2cc6150f06fc9618607908afad5af406dfcce42d 100644 --- a/src/include/kpatch_io.h +++ b/src/include/kpatch_io.h @@ -11,7 +11,7 @@ #define BUFSIZE 65536 -struct kp_file { +struct kpg_file { int id; FILE *f; @@ -31,9 +31,9 @@ struct kp_file { struct rb_root renames; }; -int read_file(struct kp_file *f, const char *fname); -int create_file(struct kp_file *f, const char *fname); -void close_file(struct kp_file *f); +int read_file(struct kpg_file *f, const char *fname); +int create_file(struct kpg_file *f, const char *fname); +void close_file(struct kpg_file *f); void *kp_realloc(void *p, int oldsz, int newsz); #endif /* __KP_IO_H__ */ diff --git a/src/include/kpatch_parse.h b/src/include/kpatch_parse.h index a36a0156eca28e4242db40bf342b11c8e588908d..038f925d7d704c5feeadbe00ee07e714d52fed9a 100644 --- a/src/include/kpatch_parse.h +++ b/src/include/kpatch_parse.h @@ -9,8 +9,8 @@ #include "rbtree.h" /* fetch code line */ -char *cline(struct kp_file *f, int l); -int clinenum(struct kp_file *f, int l); +char *cline(struct kpg_file *f, int l); +int clinenum(struct kpg_file *f, int l); /* ------------------------------------------- as directives ---------------------------------------- */ @@ -45,11 +45,11 @@ int clinenum(struct kp_file *f, int l); #define DIRECTIVE_KPFLAGS 500 -void init_multilines(struct kp_file *f); +void init_multilines(struct kpg_file *f); -void init_ctypes(struct kp_file *f); -int ctype(struct kp_file *f, int l); -int is_sect_cmd(struct kp_file *f, int l); +void init_ctypes(struct kpg_file *f); +int ctype(struct kpg_file *f, int l); +int is_sect_cmd(struct kpg_file *f, int l); int find_ctype(kpstr_t *t); @@ -69,9 +69,9 @@ struct section_desc { }; struct section_desc *find_section(char *name); -struct section_desc *csect(struct kp_file *f, int l); -void init_sections(struct kp_file *f); -void free_sections(struct kp_file *f); +struct section_desc *csect(struct kpg_file *f, int l); +void init_sections(struct kpg_file *f); +void free_sections(struct kpg_file *f); int is_data_sect(struct section_desc *sect); int is_code_sect(struct section_desc *sect); @@ -82,7 +82,7 @@ int is_code_sect(struct section_desc *sect); * it has a name, line range [start; end) and a link to matched cblock in another file (if any). */ struct cblock { - struct kp_file *f; /* file */ + struct kpg_file *f; /* file */ int start, end; /* line numbers [start;end) */ kpstr_t name; @@ -107,19 +107,19 @@ struct cblock { void get_token(char **str, kpstr_t *x); void __get_token(char **str, kpstr_t *x, const char *delim); -int is_function_start(struct kp_file *f, int l, kpstr_t *nm); -int is_function_end(struct kp_file *f, int l, kpstr_t *nm); +int is_function_start(struct kpg_file *f, int l, kpstr_t *nm); +int is_function_end(struct kpg_file *f, int l, kpstr_t *nm); void get_type_args(char *s, kpstr_t *nm, kpstr_t *attr); -int is_variable_start(struct kp_file *f, int l, int *e, int *globl, kpstr_t *nm); +int is_variable_start(struct kpg_file *f, int l, int *e, int *globl, kpstr_t *nm); int is_data_def(char *s, int type); -struct cblock *cblock_find_by_name(struct kp_file *f, kpstr_t *nm); -struct cblock *cblock_find_by_human_name(struct kp_file *f, kpstr_t *nm); -void cblocks_init(struct kp_file *f); +struct cblock *cblock_find_by_name(struct kpg_file *f, kpstr_t *nm); +struct cblock *cblock_find_by_human_name(struct kpg_file *f, kpstr_t *nm); +void cblocks_init(struct kpg_file *f); void cblock_free_by_start(struct rb_node *node); void cblock_print2(struct cblock *b0, struct cblock *b1); -struct cblock *cblock_first(struct kp_file *f); +struct cblock *cblock_first(struct kpg_file *f); struct cblock *cblock_next(struct cblock *blk); struct cblock *cblock_skip(struct cblock *blk, int type); void cblock_split(struct cblock *b, int len); diff --git a/src/kpatch_dbgfilter.c b/src/kpatch_dbgfilter.c index d385c18c9d7d991a99e0f961200a5742519dbfbf..e9a0869fc16fea39923147ead7ed60efba6d41ac 100644 --- a/src/kpatch_dbgfilter.c +++ b/src/kpatch_dbgfilter.c @@ -67,7 +67,7 @@ static int is_debug_lbl(char *s) * .Ltext0: * and the same with .Letext0 label. Match it. */ -static int skip_ltext_lbl(struct kp_file *f, int l, char *s) +static int skip_ltext_lbl(struct kpg_file *f, int l, char *s) { kpstr_t t; int n = 0; @@ -124,7 +124,7 @@ static int is_section_end(char *s, int *pl) return 0; } -static int skip_section(struct kp_file *f, int l0, char *prefix) +static int skip_section(struct kpg_file *f, int l0, char *prefix) { int l = l0; while (is_section_start(cline(f, l), prefix)) { @@ -135,23 +135,23 @@ static int skip_section(struct kp_file *f, int l0, char *prefix) return l - l0; } -static inline int skip_debug_section(struct kp_file *f, int l0) +static inline int skip_debug_section(struct kpg_file *f, int l0) { return skip_section(f, l0, ".debug_"); } -static inline int skip_eh_frame_section(struct kp_file *f, int l0) +static inline int skip_eh_frame_section(struct kpg_file *f, int l0) { return skip_section(f, l0, ".eh_frame"); } -static inline int skip_gcc_except_table(struct kp_file *f, int l0) +static inline int skip_gcc_except_table(struct kpg_file *f, int l0) { return skip_section(f, l0, ".gcc_except_table"); } /* function returns a number of lines to be removed from the tail of the file */ -static int debug_filter_skip(struct kp_file *f, int l, int options) +static int debug_filter_skip(struct kpg_file *f, int l, int options) { char *s = cline(f, l); int n; @@ -181,7 +181,7 @@ static int debug_filter_skip(struct kp_file *f, int l, int options) return 0; } -void debug_filter(struct kp_file *fin, struct kp_file *fout, int options) +void debug_filter(struct kpg_file *fin, struct kpg_file *fout, int options) { int i, n; diff --git a/src/kpatch_gensrc.c b/src/kpatch_gensrc.c index 32c7afcfc50886d39d368aefb80a7ac73fe85bd5..a7e95c789e912a9446895ecefcf99ea0d0954d4d 100644 --- a/src/kpatch_gensrc.c +++ b/src/kpatch_gensrc.c @@ -7,6 +7,9 @@ * * 2021.09.23 - kpatch_gensrc.c: support ignoring functions which we don't need * Huawei Technologies Co., Ltd. + * + * 2022.02.11 - kpatch_gensrc: fix add new global var bug + * China Telecom ******************************************************************************/ #include @@ -15,6 +18,7 @@ #include #include +#include "include/kpatch_common.h" #include "include/kpatch_log.h" #include "include/kpatch_parse.h" #include "include/kpatch_dbgfilter.h" @@ -143,7 +147,7 @@ static inline int rename_cmp(struct rb_node *node, unsigned long key) return res; } -struct rename * rename_find(struct kp_file *f, kpstr_t *nm) +struct rename * rename_find(struct kpg_file *f, kpstr_t *nm) { struct rb_node *rb; struct rename *r; @@ -156,7 +160,7 @@ struct rename * rename_find(struct kp_file *f, kpstr_t *nm) return r; } -void rename_add(struct kp_file *f, kpstr_t *src, kpstr_t *dst) +void rename_add(struct kpg_file *f, kpstr_t *src, kpstr_t *dst) { struct rename *r, *r2; @@ -181,7 +185,7 @@ void rename_add(struct kp_file *f, kpstr_t *src, kpstr_t *dst) rb_insert_node(&f->renames, &r->rb, rename_cmp, (unsigned long)src); } -void rename_del(struct kp_file *f, kpstr_t *src) +void rename_del(struct kpg_file *f, kpstr_t *src) { struct rename *r; r = rename_find(f, src); @@ -201,7 +205,7 @@ static void rename_free(struct rb_node *node) free(r); } -int strcmp_after_rename(struct kp_file *f0, struct kp_file *f1, char *s0, char *s1) +int strcmp_after_rename(struct kpg_file *f0, struct kpg_file *f1, char *s0, char *s1) { kpstr_t t0, t1; struct rename *r0, *r1; @@ -228,7 +232,7 @@ int strcmp_after_rename(struct kp_file *f0, struct kp_file *f1, char *s0, char * return !(s0 == NULL && s1 == NULL); } -void str_do_rename(struct kp_file *f, char *dst, char *src) +void str_do_rename(struct kpg_file *f, char *dst, char *src) { kpstr_t t0, *t; struct rename *r; @@ -334,7 +338,7 @@ static int is_global_rip_reference(kpstr_t *t) #define MOV_LENGTH (sizeof(MOV_PREFIX) - 1) #define MAX_FLAVOR_SIZE 16 -void str_do_gotpcrel(struct kp_file *f, char *dst, char *src) +void str_do_gotpcrel(struct kpg_file *f, char *dst, char *src) { kpstr_t mov, movsrc, movdst, tmptok; char flavor[MAX_FLAVOR_SIZE], *s = src, *d = dst; @@ -432,7 +436,7 @@ out: /* ------------------------------------------ helpers -------------------------------------------- */ -static void change_section(struct kp_file *fout, struct section_desc *sect, int flags) +static void change_section(struct kpg_file *fout, struct section_desc *sect, int flags) { static int init_data_section = 0; char *s; @@ -448,18 +452,18 @@ static void change_section(struct kp_file *fout, struct section_desc *sect, int s = ".kpatch.text,\"ax\",@progbits"; else { s = ".kpatch.data,\"aw\",@progbits"; - if (!init_data_section && !(flags & FLAG_PUSH_SECTION)) { + if (!init_data_section) { init_data_section = 1; - align = ".p2align\t12"; + align = ".p2align\t"; } } fprintf(fout->f, "\t.%ssection %s\n", (flags & FLAG_PUSH_SECTION) ? "push" : "", s); if (align) - fprintf(fout->f, "\t%s\n", align); + fprintf(fout->f, "\t%s%d\n", align, PAGE_SHIFT); } -void get_comm_args(struct kp_file *f, int l, kpstr_t *xname, int *sz, int *align) +void get_comm_args(struct kpg_file *f, int l, kpstr_t *xname, int *sz, int *align) { char *s, *p; kpstr_t t; @@ -489,7 +493,7 @@ void get_comm_args(struct kp_file *f, int l, kpstr_t *xname, int *sz, int *align /* .comm implies .bss section, while we need to put all new data to .kpatch.data, so parse and replace with other commands */ /* Surprise!!! sometimes .comm can be of a zero size for an empty struct definition :) */ -void add_comm_cmd(struct kp_file *fout, struct kp_file *f, int l, int flags) +void add_comm_cmd(struct kpg_file *fout, struct kpg_file *f, int l, int flags) { kpstr_t commname, *nm = &commname; struct rename *r; @@ -891,7 +895,7 @@ static int __cblock_var_cmp(struct cblock *b0, struct cblock *b1) return res; } -static struct cblock * cblock_var_try_to_match(struct kp_file *f0, struct kp_file *f1, struct cblock *b0, struct cblock *b1) +static struct cblock * cblock_var_try_to_match(struct kpg_file *f0, struct kpg_file *f1, struct cblock *b0, struct cblock *b1) { /* case #1: for normal variables just do a strict matching by name */ if (!b0->auto_name) @@ -971,7 +975,7 @@ static void cblock_func_match_labels(struct cblock *b0, struct cblock *b1, int a } } -static void __name_add_kpatch_suffix(struct kp_file *f, kpstr_t *t, kpstr_t *basename, const char *suffix) +static void __name_add_kpatch_suffix(struct kpg_file *f, kpstr_t *t, kpstr_t *basename, const char *suffix) { kpstr_t tnew; @@ -1020,7 +1024,7 @@ static void cblock_make_new_name(struct cblock *b, kpstr_t *basename, const char /* -------------------------------------------- analyzer ---------------------------------------------- */ -static void analyze_var_cblocks_matches(struct kp_file *f0, struct kp_file *f1) +static void analyze_var_cblocks_matches(struct kpg_file *f0, struct kpg_file *f1) { struct cblock *b0, *b1; int progress, pass = 0; @@ -1065,7 +1069,7 @@ static void analyze_var_cblocks_matches(struct kp_file *f0, struct kp_file *f1) } } -static void analyze_var_cblocks(struct kp_file *f0, struct kp_file *f1) +static void analyze_var_cblocks(struct kpg_file *f0, struct kpg_file *f1) { struct cblock *b0, *b1; @@ -1121,7 +1125,7 @@ next: ; return NULL; } -static void analyze_func_cblocks(struct kp_file *f0, struct kp_file *f1) +static void analyze_func_cblocks(struct kpg_file *f0, struct kpg_file *f1) { struct cblock *b0, *b1; int progress, cmp, not_adapted=0; @@ -1273,7 +1277,7 @@ static void analyze_func_cblocks(struct kp_file *f0, struct kp_file *f1) kpfatal("not adapted function found\n"); } -static void analyze_other_cblocks(struct kp_file *f0, struct kp_file *f1) +static void analyze_other_cblocks(struct kpg_file *f0, struct kpg_file *f1) { struct cblock *b0, *b1; @@ -1301,7 +1305,7 @@ done: } /* output of single block line with renames done if needed */ -static void cblock_write_line(struct kp_file *fout, struct cblock *b, int l, int flags) +static void cblock_write_line(struct kpg_file *fout, struct cblock *b, int l, int flags) { char buf[2*BUFSIZE], buf2[2*BUFSIZE], *s; @@ -1322,7 +1326,7 @@ static void cblock_write_line(struct kp_file *fout, struct cblock *b, int l, int fprintf(fout->f, "; "); } -static void cblock_write(struct kp_file *fout, struct cblock *b, int flags) +static void cblock_write(struct kpg_file *fout, struct cblock *b, int flags) { int i; @@ -1330,7 +1334,7 @@ static void cblock_write(struct kp_file *fout, struct cblock *b, int flags) cblock_write_line(fout, b, i, flags); } -static void cblock_write_other(struct kp_file *fout, struct cblock *b) +static void cblock_write_other(struct kpg_file *fout, struct cblock *b) { cblock_write(fout, b, 0); b->handled = 1; @@ -1338,7 +1342,7 @@ static void cblock_write_other(struct kp_file *fout, struct cblock *b) b->pair->handled = 1; } -static void cblock_write_attr(struct kp_file *fout, struct cblock *b, struct cblock *bpair) +static void cblock_write_attr(struct kpg_file *fout, struct cblock *b, struct cblock *bpair) { cblock_write(fout, b, FLAG_RENAME); b->handled = 1; @@ -1349,7 +1353,7 @@ static void cblock_write_attr(struct kp_file *fout, struct cblock *b, struct cbl } } -static void cblock_write_var(struct kp_file *fout, struct cblock *b) +static void cblock_write_var(struct kpg_file *fout, struct cblock *b) { fprintf(fout->f, "#---------- var ---------\n"); /* if new variable became global, then mark the old one as well */ @@ -1361,7 +1365,7 @@ static void cblock_write_var(struct kp_file *fout, struct cblock *b) b->pair->handled = 1; } -static void __cblock_gen(struct kp_file *fout, struct cblock *b, int flags) +static void __cblock_gen(struct kpg_file *fout, struct cblock *b, int flags) { int i, t; @@ -1391,7 +1395,7 @@ static void __cblock_gen(struct kp_file *fout, struct cblock *b, int flags) } /* Add new code/data. Puts it into appropriate sections depending on the source section (.text/.data). */ -static void cblock_gen(struct kp_file *fout, struct cblock *b, int flags) +static void cblock_gen(struct kpg_file *fout, struct cblock *b, int flags) { change_section(fout, csect(b->f, b->start), FLAG_PUSH_SECTION); if (force_global && b->type == CBLOCK_FUNC) @@ -1405,13 +1409,13 @@ static void cblock_gen(struct kp_file *fout, struct cblock *b, int flags) /* 32 bit binary can't contain 64 bit relocations. * thus we forced to split .quad to two .long on x86 */ -static inline void pad2quad(struct kp_file *fout) +static inline void pad2quad(struct kpg_file *fout) { if (arch_bits == 32) fprintf(fout->f, "\t.long 0\n"); } -static void write_new_function(struct kp_file *fout, struct cblock *b) +static void write_new_function(struct kpg_file *fout, struct cblock *b) { static int nsyms = 0; char *s = b->name.s; @@ -1466,7 +1470,7 @@ static void write_new_function(struct kp_file *fout, struct cblock *b) fprintf(fout->f, "\n"); } -static void cblock_write_func(struct kp_file *f0, struct kp_file *fout, struct cblock *b) +static void cblock_write_func(struct kpg_file *f0, struct kpg_file *fout, struct cblock *b) { /* write original function */ kplog(LOG_TRACE, "cblock_write_func %.*s\n", b->name.l, b->name.s); @@ -1498,7 +1502,7 @@ done: } -static void write_cblocks(struct kp_file *f0, struct kp_file *f1, struct kp_file *fout) +static void write_cblocks(struct kpg_file *f0, struct kpg_file *f1, struct kpg_file *fout) { struct cblock *b0, *b1; @@ -1663,14 +1667,14 @@ int main(int argc, char **argv) { int err, ch, k = 0, dbgfilter = 0, dbgfilter_options = 0; int test_mode = 0; - struct kp_file infile[2], outfile; + struct kpg_file infile[2], outfile; int ret = -1; - memset(&infile[0], 0, sizeof(struct kp_file)); + memset(&infile[0], 0, sizeof(struct kpg_file)); infile[0].f = NULL; - memset(&infile[1], 0, sizeof(struct kp_file)); + memset(&infile[1], 0, sizeof(struct kpg_file)); infile[1].f = NULL; - memset(&outfile, 0, sizeof(struct kp_file)); + memset(&outfile, 0, sizeof(struct kpg_file)); outfile.f = NULL; while ((ch = getopt_long(argc, argv, "d:O:i:o:a:f", long_opts, 0)) != -1) { switch (ch) { diff --git a/src/kpatch_io.c b/src/kpatch_io.c index 08f6e460988775a923bd791441f6c79832d4f4e9..f301cd2ebd10c69b127df1e130db3384260a9f27 100644 --- a/src/kpatch_io.c +++ b/src/kpatch_io.c @@ -40,7 +40,7 @@ static char *kp_strdup(const char *s) return new; } -int read_file(struct kp_file *file, const char *fname) +int read_file(struct kpg_file *file, const char *fname) { int sz = 64; char buf[BUFSIZE]; @@ -84,7 +84,7 @@ int read_file(struct kp_file *file, const char *fname) return 0; } -int create_file(struct kp_file *file, const char *fname) +int create_file(struct kpg_file *file, const char *fname) { if (!strcmp(fname, "-")) { file->f = stdout; @@ -97,7 +97,7 @@ int create_file(struct kp_file *file, const char *fname) return 0; } -void close_file(struct kp_file *file) +void close_file(struct kpg_file *file) { int i; diff --git a/src/kpatch_parse.c b/src/kpatch_parse.c index ddf58f867c9e19774be46fd165168e4a606e20f6..8f1486d2ead0cb3d08fe3b13323aa861707cdbbb 100644 --- a/src/kpatch_parse.c +++ b/src/kpatch_parse.c @@ -10,6 +10,9 @@ * * 2021.10.08 - kpatch_parse: fix possible Null pointer dereferences * Huawei Technologies Co., Ltd. + * + * 2022.02.11 - kpatch_parse: fix add new global var bug + * China Telecom ******************************************************************************/ #include @@ -18,7 +21,7 @@ #include "include/kpatch_parse.h" #include "include/kpatch_flags.h" -char *cline(struct kp_file *f, int l) +char *cline(struct kpg_file *f, int l) { if (l < 0 || l >= f->nr_lines) return NULL; @@ -26,7 +29,7 @@ char *cline(struct kp_file *f, int l) return f->lines[l]; } -int clinenum(struct kp_file *f, int l) +int clinenum(struct kpg_file *f, int l) { if (l < 0 || l >= f->nr_lines) return 0; @@ -133,7 +136,7 @@ int find_ctype(kpstr_t *t) return -1; } -int ctype(struct kp_file *f, int l) +int ctype(struct kpg_file *f, int l) { if (l >= f->nr_lines) kpfatal("ctype access beyond EOF"); @@ -141,7 +144,7 @@ int ctype(struct kp_file *f, int l) return f->ctype[l]; } -int is_sect_cmd(struct kp_file *f, int l) +int is_sect_cmd(struct kpg_file *f, int l) { int t = ctype(f, l); @@ -150,13 +153,13 @@ int is_sect_cmd(struct kp_file *f, int l) t == DIRECTIVE_PREVIOUS || t == DIRECTIVE_SUBSECTION; } -void init_ctypes(struct kp_file *f) +void init_ctypes(struct kpg_file *f) { int i; f->ctype = malloc(f->nr_lines * sizeof(f->ctype[0])); if (!f->ctype) { - kpfatal("Failed to allocate ctype for kp_file\n"); + kpfatal("Failed to allocate ctype for kpg_file\n"); } for (i = 0; i < f->nr_lines; i++) { @@ -219,7 +222,7 @@ static void cblock_make_human_name(kpstr_t *hnm, kpstr_t *nm) hnm->l--; } -struct cblock * cblock_add(struct kp_file *f, int s, int e, kpstr_t *nm, int type, int globl) +struct cblock * cblock_add(struct kpg_file *f, int s, int e, kpstr_t *nm, int type, int globl) { struct cblock *blk = malloc(sizeof(*blk)); if (!blk) { @@ -247,7 +250,7 @@ struct cblock * cblock_add(struct kp_file *f, int s, int e, kpstr_t *nm, int typ return blk; } -struct cblock *cblock_find_by_name(struct kp_file *f, kpstr_t *nm) +struct cblock *cblock_find_by_name(struct kpg_file *f, kpstr_t *nm) { struct rb_node *rb; struct cblock *blk; @@ -260,7 +263,7 @@ struct cblock *cblock_find_by_name(struct kp_file *f, kpstr_t *nm) return blk; } -struct cblock *cblock_find_by_human_name(struct kp_file *f, kpstr_t *nm) +struct cblock *cblock_find_by_human_name(struct kpg_file *f, kpstr_t *nm) { struct rb_node *n, *n2; struct cblock *blk; @@ -297,7 +300,7 @@ static int get_kpatch_flags(char *s) return flags; } -static void init_func_block(struct kp_file *f, int *i, kpstr_t *nm) +static void init_func_block(struct kpg_file *f, int *i, kpstr_t *nm) { int s = *i, e = *i, globl = 0; int flags = 0; @@ -321,7 +324,7 @@ static void init_func_block(struct kp_file *f, int *i, kpstr_t *nm) *i = e; } -static void init_var_block(struct kp_file *f, int *i, kpstr_t *nm) +static void init_var_block(struct kpg_file *f, int *i, kpstr_t *nm) { int s = *i, e = *i, e2, globl = 0; kpstr_t nm2; @@ -348,7 +351,7 @@ static void init_var_block(struct kp_file *f, int *i, kpstr_t *nm) *i = e; } -static void init_set_block(struct kp_file *f, int *i, kpstr_t *nm) +static void init_set_block(struct kpg_file *f, int *i, kpstr_t *nm) { char *s = cline(f, *i); get_token(&s, nm); @@ -357,7 +360,7 @@ static void init_set_block(struct kp_file *f, int *i, kpstr_t *nm) (*i)++; } -static void init_other_block(struct kp_file *f, int *i) +static void init_other_block(struct kpg_file *f, int *i) { int s = *i, e = *i; kpstr_t nm; @@ -370,7 +373,7 @@ static void init_other_block(struct kp_file *f, int *i) *i = e; } -static void init_attr_block(struct kp_file *f, int *i) +static void init_attr_block(struct kpg_file *f, int *i) { kpstr_t nm; char *s = cline(f, *i); @@ -403,7 +406,7 @@ void cblock_split(struct cblock *b, int len) kplog(LOG_DEBUG, "Add split cblock %.*s (%d: %d-%d)\n", blk->name.l, blk->name.s, blk->f->id, blk->start, blk->end - 1); } -void cblocks_init(struct kp_file *f) +void cblocks_init(struct kpg_file *f) { int i; kpstr_t nm; @@ -447,7 +450,7 @@ void cblock_print2(struct cblock *b0, struct cblock *b1) i1 < b1->end ? cline(b1->f, i1) : ""); } -struct cblock *cblock_first(struct kp_file *f) +struct cblock *cblock_first(struct kpg_file *f) { struct rb_node *n = rb_first(&f->cblocks_by_start); if (!n) @@ -550,7 +553,7 @@ static struct section_desc *dup_section(struct section_desc *sect) return s; } -struct section_desc *csect(struct kp_file *f, int l) +struct section_desc *csect(struct kpg_file *f, int l) { struct section_desc *sect; @@ -617,7 +620,7 @@ done: return sect; } -static struct section_desc *parse_section(struct kp_file *f, int l) +static struct section_desc *parse_section(struct kpg_file *f, int l) { int t; struct section_desc *cur = f->section[l - 1], *new; @@ -641,7 +644,7 @@ static struct section_desc *parse_section(struct kp_file *f, int l) return NULL; } -void init_sections(struct kp_file *f) +void init_sections(struct kpg_file *f) { struct section_desc *sect; int i; @@ -652,7 +655,7 @@ void init_sections(struct kp_file *f) f->section = malloc(f->nr_lines * sizeof(void *)); if (!f->section) { - kpfatal("Failed to allocate section for kp_file\n"); + kpfatal("Failed to allocate section for kpg_file\n"); } f->section[0] = find_section(".text"); /* code can start w/o sectiong directive */ @@ -667,7 +670,7 @@ void init_sections(struct kp_file *f) } } -void free_sections(struct kp_file *f) +void free_sections(struct kpg_file *f) { struct section_desc **secs = NULL; int i; @@ -686,7 +689,7 @@ void free_sections(struct kp_file *f) } /* ----------------------------------------- code block boundaries detection ---------------------------------------- */ -int is_function_end(struct kp_file *f, int l, kpstr_t *nm) +int is_function_end(struct kpg_file *f, int l, kpstr_t *nm) { /* Functions should always end by .size directive. Previously used to detect .LFe labels, but they are not generated w/o frame pointers */ if (ctype(f, l) != DIRECTIVE_SIZE) diff --git a/src/kpatch_patch.c b/src/kpatch_patch.c index d74299d8a7bbbd3dd363d90dfbea38999d22acd7..590f08258cc37d84c5e16034eeb373966d13cd1b 100644 --- a/src/kpatch_patch.c +++ b/src/kpatch_patch.c @@ -28,6 +28,9 @@ * * 2021.09.23 - libcare-ctl: implement applied patch list * Huawei Technologies Co., Ltd. + * + * 2022.02.11 - libcare-ctl: fix add new global var bug + * China Telecom ******************************************************************************/ #include @@ -372,9 +375,9 @@ object_apply_patch(struct object_file *o) kp->jmp_offset = sz; kpdebug("Jump table %d bytes for %d syms at offset 0x%x\n", o->jmp_table->size, undef, kp->jmp_offset); - sz = ROUND_UP(sz + o->jmp_table->size, 4096); + sz = ROUND_UP(sz + o->jmp_table->size, PAGE_SIZE); } - sz = ROUND_UP(sz, 4096); + sz = ROUND_UP(sz, PAGE_SIZE); /* kpatch elf */ kp->elf_offset = sz; @@ -386,7 +389,7 @@ object_apply_patch(struct object_file *o) kp->user_undo = sz; sz = ROUND_UP(sz + HUNK_SIZE * o->ninfo, 16); - sz = ROUND_UP(sz, 4096); + sz = ROUND_UP(sz, PAGE_SIZE); kp->kpatch_total_mem_sz = sz; /* diff --git a/tests/new_var/Makefile b/tests/new_var/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..6dd4b693574de6c1717d7c887d650e00af2b7466 --- /dev/null +++ b/tests/new_var/Makefile @@ -0,0 +1,2 @@ + +include ../makefile.inc diff --git a/tests/new_var/desc b/tests/new_var/desc new file mode 100644 index 0000000000000000000000000000000000000000..4f8cd31e25c3d5fef9b480064c65aaf9626dfd7f --- /dev/null +++ b/tests/new_var/desc @@ -0,0 +1 @@ +patch adds a new var diff --git a/tests/new_var/new_var.c b/tests/new_var/new_var.c new file mode 100644 index 0000000000000000000000000000000000000000..3ed116ad6b8517b079de57b7d0e7b3d4e2a8d847 --- /dev/null +++ b/tests/new_var/new_var.c @@ -0,0 +1,23 @@ +#include +#include + +void print_greetings_patched(int var) +{ + printf("Hello. This is a PATCHED version\n"); + printf("Hello. \n", var); +} + +void print_greetings(void) +{ + printf("Hello. This is an UNPATCHED version\n"); +} + +int main() +{ + while (1) { + print_greetings(); + sleep(1); + } + + return 0; +} diff --git a/tests/new_var/new_var.diff b/tests/new_var/new_var.diff new file mode 100644 index 0000000000000000000000000000000000000000..c61753563f7dd812b518984bef00ecb65da738d0 --- /dev/null +++ b/tests/new_var/new_var.diff @@ -0,0 +1,15 @@ +--- ./new_var.c 2022-02-10 19:40:17.948981115 +0800 ++++ ./new_var.c 2022-02-10 20:02:38.774536002 +0800 +@@ -7,9 +7,11 @@ + printf("Hello. \n", var); + } + ++int newly_added_var = 0x20220210; + void print_greetings(void) + { +- printf("Hello. This is an UNPATCHED version\n"); ++ newly_added_var = 0x2022 << 16 | 0x2202; ++ print_greetings_patched(newly_added_var); + } + + int main()