Commit 489745f2 authored by Cyrill Gorcunov's avatar Cyrill Gorcunov

restore: A number of fixups and debug printing

An idea is to align restorer size to be sure it
wont be stripped in a middle of code.
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@gmail.com>
parent ed3c4fba
...@@ -23,7 +23,7 @@ MAKE := make ...@@ -23,7 +23,7 @@ MAKE := make
CFLAGS += -I./include CFLAGS += -I./include
CFLAGS += -O0 -ggdb3 CFLAGS += -O0 -ggdb3
LIBS += -lrt LIBS += -lrt -lpthread
# Additional ARCH settings for x86 # Additional ARCH settings for x86
ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \ ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
...@@ -109,7 +109,7 @@ $(OBJS): $(HEAD-BLOB) $(DEPS) $(HEAD-BLOB-GEN) ...@@ -109,7 +109,7 @@ $(OBJS): $(HEAD-BLOB) $(DEPS) $(HEAD-BLOB-GEN)
$(E) " CC " $@ $(E) " CC " $@
$(Q) $(CC) -c $(CFLAGS) $< -o $@ $(Q) $(CC) -c $(CFLAGS) $< -o $@
$(PROGRAM): $(OBJS) $(PROGRAM): $(OBJS) restorer.o
$(E) " LINK " $@ $(E) " LINK " $@
$(Q) $(CC) $(CFLAGS) $(OBJS) $(LIBS) -o $@ $(Q) $(CC) $(CFLAGS) $(OBJS) $(LIBS) -o $@
...@@ -124,6 +124,13 @@ test: ...@@ -124,6 +124,13 @@ test:
$(Q) $(MAKE) -C test all $(Q) $(MAKE) -C test all
.PHONY: test .PHONY: test
rebuild:
$(E) " FORCE-REBUILD"
$(Q) $(RM) -f ./*.o
$(Q) $(RM) -f ./*.d
$(Q) $(MAKE)
.PHONY: rebuild
clean: clean:
$(E) " CLEAN" $(E) " CLEAN"
$(Q) $(RM) -f ./*.o $(Q) $(RM) -f ./*.o
......
...@@ -1262,7 +1262,7 @@ static void restorer_test(pid_t pid) ...@@ -1262,7 +1262,7 @@ static void restorer_test(pid_t pid)
code_len = restorer_fcall(RESTORER_CMD__GET_SELF_LEN) - (long)restorer; code_len = restorer_fcall(RESTORER_CMD__GET_SELF_LEN) - (long)restorer;
args_offset = restorer_fcall(RESTORER_CMD__GET_ARG_OFFSET) - (long)restorer; args_offset = restorer_fcall(RESTORER_CMD__GET_ARG_OFFSET) - (long)restorer;
code_len = round_up(code_len, 16); code_len = round_up(code_len, 16);
vma_len = round_up(code_len + RESTORER_STACK_SIZE, PAGE_SIZE); vma_len = round_up(code_len + RESTORER_STACK_SIZE + RESTORER_STACK_FRAME, PAGE_SIZE);
/* /*
* Here we need some heuristics -- the VMA which restorer will * Here we need some heuristics -- the VMA which restorer will
...@@ -1280,28 +1280,30 @@ static void restorer_test(pid_t pid) ...@@ -1280,28 +1280,30 @@ static void restorer_test(pid_t pid)
return; return;
} }
/* /*
* Prepare a stack for the restorer. It's a bit * Prepare a stack for the restorer. It's a bit
* tricky -- since compiler generates function * tricky -- since compiler generates function
* prologue we need to manually tune up stack * prologue we need to manually tune up stack
* value. * value.
*/ */
exec_start = exec_mem + RESTORER_STACK_SIZE; memzero(exec_mem, RESTORER_STACK_SIZE + RESTORER_STACK_FRAME);
memzero(exec_mem, RESTORER_STACK_SIZE); exec_start = exec_mem + RESTORER_STACK_SIZE + RESTORER_STACK_FRAME;
/* Restorer content at the new location */ /* Restorer content at the new location */
memcpy(exec_start, &restorer, code_len); memcpy(exec_start, &restorer, code_len);
restorer_fcall = exec_start; restorer_fcall = exec_start;
/* /*
* Stack pointer in a middle of allocated stack zone. * Adjust stack with red-zone area.
*/ */
new_sp = (long)exec_mem + RESTORER_STACK_MIDDLE; new_sp = (long)exec_mem + RESTORER_STACK_SIZE - RESTORER_STACK_REDZONE;
/* /*
* Pass arguments and run a command. * Pass arguments and run a command.
*/ */
args = (struct restore_core_args *)(exec_start + args_offset); args = (struct restore_core_args *)(exec_start + args_offset);
args->rt_sigframe = (void *)((long)exec_mem + RESTORER_STACK_SIZE + RESTORER_STACK_REDZONE);
args->self_entry = exec_mem; args->self_entry = exec_mem;
args->self_size = vma_len; args->self_size = vma_len;
...@@ -1310,6 +1312,14 @@ static void restorer_test(pid_t pid) ...@@ -1310,6 +1312,14 @@ static void restorer_test(pid_t pid)
snprintf(path, sizeof(path), "core-%d.img", pid); snprintf(path, sizeof(path), "core-%d.img", pid);
strcpy(args->core_path, path); strcpy(args->core_path, path);
pr_info("vma_len: %li code_len: %li exec_mem: %p exec_start: %p new_sp: %p args: %p\n",
vma_len, code_len, exec_mem, exec_start, new_sp, args);
pr_info("args: %p args->rt_sigframe: %p args->self_entry: %p \nargs->self_size: %p "
"args->self_vmas_path: %p args->core_path: %p\n",
args, args->rt_sigframe, args->self_entry, args->self_size,
args->self_vmas_path, args->core_path);
/* /*
* An indirect call to restorer, note it never resturns * An indirect call to restorer, note it never resturns
* and restoreing core is extremely destructive. * and restoreing core is extremely destructive.
......
...@@ -12,10 +12,11 @@ ...@@ -12,10 +12,11 @@
#endif #endif
#define RESTORER_ARGS_SIZE 512 #define RESTORER_ARGS_SIZE 512
#define RESTORER_STACK_MIDDLE (16 << 10) #define RESTORER_STACK_REDZONE (128)
#define RESTORER_STACK_SIZE (RESTORER_STACK_MIDDLE * 2) #define RESTORER_STACK_FRAME (16 << 10)
#define RESTORER_STACK_SIZE (32 << 10)
long restorer(long cmd); extern long restorer(long cmd);
typedef long (*restorer_fcall_t) (long cmd); typedef long (*restorer_fcall_t) (long cmd);
...@@ -27,18 +28,61 @@ typedef long (*restorer_fcall_t) (long cmd); ...@@ -27,18 +28,61 @@ typedef long (*restorer_fcall_t) (long cmd);
#define ABI_RED_ZONE 128 #define ABI_RED_ZONE 128
#define align_sigframe(sp) \ #define align_sigframe(sp) round_down(sp, 16) - 8
do { \
sp = round_down(sp, 16) - 8; \
} while (0)
struct restore_core_args { struct restore_core_args {
void *self_entry; /* restorer placed at */ void *self_entry; /* restorer placed at */
void *rt_sigframe; /* sigframe placed at */
long self_size; /* size for restorer granted */ long self_size; /* size for restorer granted */
char core_path[64]; /* path to a core file */ char core_path[64]; /* path to a core file */
char self_vmas_path[64]; /* path to a self-vmas file */ char self_vmas_path[64]; /* path to a self-vmas file */
}; };
struct pt_regs {
unsigned long r15;
unsigned long r14;
unsigned long r13;
unsigned long r12;
unsigned long bp;
unsigned long bx;
unsigned long r11;
unsigned long r10;
unsigned long r9;
unsigned long r8;
unsigned long ax;
unsigned long cx;
unsigned long dx;
unsigned long si;
unsigned long di;
unsigned long orig_ax;
unsigned long ip;
unsigned long cs;
unsigned long flags;
unsigned long sp;
unsigned long ss;
};
struct partial_pt_regs {
unsigned long r11;
unsigned long r10;
unsigned long r9;
unsigned long r8;
unsigned long ax;
unsigned long cx;
unsigned long dx;
unsigned long si;
unsigned long di;
unsigned long orig_ax;
unsigned long ip;
unsigned long cs;
unsigned long flags;
unsigned long sp;
unsigned long ss;
};
struct rt_sigcontext { struct rt_sigcontext {
unsigned long r8; unsigned long r8;
unsigned long r9; unsigned long r9;
......
...@@ -42,6 +42,8 @@ ...@@ -42,6 +42,8 @@
#define inline_memzero(d,l) __builtin_memset(d,0,l) #define inline_memzero(d,l) __builtin_memset(d,0,l)
#define inline_memzero_p(d) __builtin_memset(d,0,sizeof(*(d))) #define inline_memzero_p(d) __builtin_memset(d,0,sizeof(*(d)))
#define sigframe_addr(p) ((long)p)
static void always_inline write_char(char c) static void always_inline write_char(char c)
{ {
sys_write(1, &c, 1); sys_write(1, &c, 1);
...@@ -67,7 +69,6 @@ static void always_inline write_string_n(char *str) ...@@ -67,7 +69,6 @@ static void always_inline write_string_n(char *str)
static void always_inline write_hex_n(unsigned long num) static void always_inline write_hex_n(unsigned long num)
{ {
bool tailing = false;
unsigned char *s = (unsigned char *)&num; unsigned char *s = (unsigned char *)&num;
unsigned char c; unsigned char c;
int i; int i;
...@@ -152,6 +153,8 @@ self_len_end: ...@@ -152,6 +153,8 @@ self_len_end:
struct user_regs_entry *gpregs; struct user_regs_entry *gpregs;
struct rt_sigframe *rt_sigframe; struct rt_sigframe *rt_sigframe;
unsigned long new_sp, *stack;
lea_args_off(args); lea_args_off(args);
write_string_n(args->core_path); write_string_n(args->core_path);
...@@ -296,13 +299,9 @@ self_len_end: ...@@ -296,13 +299,9 @@ self_len_end:
* by the kernel with stack overflow error. * by the kernel with stack overflow error.
*/ */
/* rt_sigframe = args->rt_sigframe;
* Reuse arguments space for own needs, write_hex_n((long)rt_sigframe);
* no more arguments needed so lets try write_hex_n((long)&rt_sigframe->uc);
* to be thrifty with memory usage.
*/
lea_args_off(rt_sigframe);
inline_memzero_p(rt_sigframe);
#define CPREG1(d) rt_sigframe->uc.uc_mcontext.d = core_entry.u.arch.gpregs.d #define CPREG1(d) rt_sigframe->uc.uc_mcontext.d = core_entry.u.arch.gpregs.d
#define CPREG2(d,s) rt_sigframe->uc.uc_mcontext.d = core_entry.u.arch.gpregs.s #define CPREG2(d,s) rt_sigframe->uc.uc_mcontext.d = core_entry.u.arch.gpregs.s
...@@ -331,7 +330,10 @@ self_len_end: ...@@ -331,7 +330,10 @@ self_len_end:
/* FIXME: What with cr2 and friends which are rest there? */ /* FIXME: What with cr2 and friends which are rest there? */
write_hex_n(__LINE__); new_sp = core_entry.u.arch.gpregs.sp - 8;
write_hex_n(new_sp);
stack = (void *)new_sp;
*stack = (long)rt_sigframe;
/* /*
* Prepare the stack and call for sigreturn, * Prepare the stack and call for sigreturn,
...@@ -344,7 +346,7 @@ self_len_end: ...@@ -344,7 +346,7 @@ self_len_end:
"movl $"__stringify(__NR_rt_sigreturn)", %%eax \t\n" "movl $"__stringify(__NR_rt_sigreturn)", %%eax \t\n"
"syscall \t\n" "syscall \t\n"
: :
: "r"((long)rt_sigframe + sizeof(*rt_sigframe)) : "r"(new_sp)
: "rax","rsp","memory"); : "rax","rsp","memory");
core_restore_end: core_restore_end:
...@@ -364,11 +366,11 @@ core_restore_end: ...@@ -364,11 +366,11 @@ core_restore_end:
self_len_start: self_len_start:
asm volatile( asm volatile(
".align 16 \t\n" ".align 64 \t\n"
"self: \t\n" "self: \t\n"
"leaq self(%%rip), %%rax \t\n" "leaq self(%%rip), %%rax \t\n"
"addq $16, %%rax \t\n" "addq $64, %%rax \t\n"
"andq $~15, %%rax \t\n" "andq $~63, %%rax \t\n"
"movq %%rax, %0 \t\n" "movq %%rax, %0 \t\n"
: "=r"(ret) : "=r"(ret)
: :
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment