diff --git a/compel/include/uapi/infect.h b/compel/include/uapi/infect.h index 746026c19..142bef6fe 100644 --- a/compel/include/uapi/infect.h +++ b/compel/include/uapi/infect.h @@ -139,8 +139,8 @@ struct parasite_blob_desc { union { struct { const void *mem; - size_t bsize; /* size of the blob */ - size_t size; /* size of the blob with relocs */ + size_t bsize; + size_t nr_gotpcrel; unsigned long parasite_ip_off; unsigned long addr_cmd_off; unsigned long addr_arg_off; diff --git a/compel/src/lib/infect.c b/compel/src/lib/infect.c index bbb373a91..6674dc0f6 100644 --- a/compel/src/lib/infect.c +++ b/compel/src/lib/infect.c @@ -838,10 +838,15 @@ int compel_map_exchange(struct parasite_ctl *ctl, unsigned long size) return ret; } +static inline unsigned long total_pie_size(size_t blob_size, size_t nr_gp) +{ + return round_up(blob_size + nr_gp * sizeof(long), page_size()); +} + int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned long args_size) { int ret; - unsigned long p, map_exchange_size, parasite_size = 0; + unsigned long p, map_exchange_size, pie_size, parasite_size = 0; if (ctl->pblob.parasite_type != COMPEL_BLOB_CHEADER) goto err; @@ -859,7 +864,7 @@ int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned l * without using ptrace at all. */ - parasite_size = ctl->pblob.hdr.size; + pie_size = parasite_size = total_pie_size(ctl->pblob.hdr.bsize, ctl->pblob.hdr.nr_gotpcrel); ctl->args_size = round_up(args_size, PAGE_SIZE); parasite_size += ctl->args_size; @@ -879,7 +884,7 @@ int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned l ctl->addr_cmd = ctl->local_map + ctl->pblob.hdr.addr_cmd_off; ctl->addr_args = ctl->local_map + ctl->pblob.hdr.addr_arg_off; - memcpy(ctl->local_map, ctl->pblob.hdr.mem, ctl->pblob.hdr.size); + memcpy(ctl->local_map, ctl->pblob.hdr.mem, pie_size); if (ctl->pblob.hdr.nr_relocs) compel_relocs_apply(ctl->local_map, ctl->remote_map, ctl->pblob.hdr.bsize, ctl->pblob.hdr.relocs, ctl->pblob.hdr.nr_relocs); diff --git a/criu/parasite-syscall.c b/criu/parasite-syscall.c index 445df2725..9dd253007 100644 --- a/criu/parasite-syscall.c +++ b/criu/parasite-syscall.c @@ -547,9 +547,9 @@ static int make_sigframe(void *arg, struct rt_sigframe *sf, struct rt_sigframe * #endif #define init_blob_desc(bdesc, blob_type) do { \ - bdesc->hdr.size = pie_size(parasite_##blob_type); \ bdesc->hdr.mem = parasite_##blob_type##_blob; \ bdesc->hdr.bsize = sizeof(parasite_##blob_type##_blob); \ + bdesc->hdr.nr_gotpcrel = pie_nr_gotpcrel(parasite_##blob_type); \ /* Setup the rest of a control block */ \ bdesc->hdr.parasite_ip_off = pblob_offset(blob_type, __export_parasite_head_start);\ bdesc->hdr.addr_cmd_off = pblob_offset(blob_type, __export_parasite_cmd); \ diff --git a/criu/pie/pie-relocs.h b/criu/pie/pie-relocs.h index 442e70d13..a96150a26 100644 --- a/criu/pie/pie-relocs.h +++ b/criu/pie/pie-relocs.h @@ -10,6 +10,7 @@ #define pie_size(__pie_name) (round_up(sizeof(__pie_name##_blob) + \ __pie_name ## _nr_gotpcrel * sizeof(long), page_size())) +#define pie_nr_gotpcrel(__pie_name) (__pie_name ## _nr_gotpcrel) #define ELF_RELOCS_APPLY(__pie_name, __mem, __vbase) \ compel_relocs_apply(__mem, __vbase, sizeof(__pie_name##_blob), \ __pie_name##_relocs, ARRAY_SIZE(__pie_name##_relocs)) @@ -17,6 +18,7 @@ #else #define pie_size(__pie_name) (round_up(sizeof(__pie_name##_blob), page_size())) +#define pie_nr_gotpcrel(__pie_name) (0) #define ELF_RELOCS_APPLY(__pie_name, __mem, __vbase) #endif