Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

attaching to a running process. #360

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions Makefile
Expand Up @@ -186,6 +186,7 @@ LIBMCOUNT_UTILS_SRCS += $(srcdir)/utils/rbtree.c $(srcdir)/utils/filter.c
LIBMCOUNT_UTILS_SRCS += $(srcdir)/utils/demangle.c $(srcdir)/utils/utils.c
LIBMCOUNT_UTILS_SRCS += $(srcdir)/utils/script.c $(srcdir)/utils/script-python.c $(srcdir)/utils/script-luajit.c
LIBMCOUNT_UTILS_SRCS += $(srcdir)/utils/auto-args.c $(srcdir)/utils/dwarf.c
LIBMCOUNT_UTILS_SRCS += $(srcdir)/utils/env-file.c
LIBMCOUNT_UTILS_SRCS += $(wildcard $(srcdir)/utils/symbol*.c)
LIBMCOUNT_UTILS_OBJS := $(patsubst $(srcdir)/utils/%.c,$(objdir)/libmcount/%.op,$(LIBMCOUNT_UTILS_SRCS))

Expand Down
14 changes: 14 additions & 0 deletions arch/aarch64/mcount-arch.h
@@ -1,6 +1,20 @@
#ifndef MCOUNT_ARCH_H
#define MCOUNT_ARCH_H

#include <sys/user.h>
#define ARCH_REGS struct user_regs_struct
#define ARCH_PC_TYPE typeof(((ARCH_REGS *)0)->pc)

inline ARCH_PC_TYPE get_pc(ARCH_REGS regs)
{
return regs.pc;
}

inline void set_pc(ARCH_REGS *regs, ARCH_PC_TYPE pc)
{
regs->pc = pc;
}

#define mcount_regs mcount_regs

struct mcount_regs {
Expand Down
14 changes: 14 additions & 0 deletions arch/arm/mcount-arch.h
@@ -1,6 +1,20 @@
#ifndef MCOUNT_ARCH_H
#define MCOUNT_ARCH_H

#include <sys/user.h>
#define ARCH_REGS struct user_regs
#define ARCH_PC_TYPE typeof(((ARCH_REGS *)0)->uregs[0])

inline ARCH_PC_TYPE get_pc(ARCH_REGS regs)
{
return regs.uregs[15];
}

inline void set_pc(ARCH_REGS *regs, ARCH_PC_TYPE pc)
{
regs->uregs[15] = pc;
}

#define mcount_regs mcount_regs

struct mcount_regs {
Expand Down
14 changes: 14 additions & 0 deletions arch/i386/mcount-arch.h
Expand Up @@ -2,6 +2,20 @@
#ifndef __MCOUNT_ARCH_H__
#define __MCOUNT_ARCH_H__

#include <sys/user.h>
#define ARCH_REGS struct user_regs_struct
#define ARCH_PC_TYPE typeof(((ARCH_REGS *)0)->eip)

inline ARCH_PC_TYPE get_pc(ARCH_REGS regs)
{
return regs.eip;
}

inline void set_pc(ARCH_REGS *regs, ARCH_PC_TYPE pc)
{
regs->eip = pc;
}

#define mcount_regs mcount_regs

struct mcount_regs {
Expand Down
4 changes: 3 additions & 1 deletion arch/x86_64/Makefile
Expand Up @@ -8,17 +8,19 @@ include $(srcdir)/Makefile.include
ARCH_ENTRY_SRC = $(wildcard $(sdir)/*.S)
ARCH_MCOUNT_SRC = $(wildcard $(sdir)/mcount-*.c) $(sdir)/symbol.c
ARCH_UFTRACE_SRC = $(sdir)/cpuinfo.c $(sdir)/symbol.c
ARCH_ATTACH_ASM = $(wildcard $(sdir)/inject*.S)

ARCH_MCOUNT_OBJS = $(patsubst $(sdir)/%.S,$(odir)/%.op,$(ARCH_ENTRY_SRC))
ARCH_MCOUNT_OBJS += $(patsubst $(sdir)/%.c,$(odir)/%.op,$(ARCH_MCOUNT_SRC))
ARCH_UFTRACE_OBJS = $(patsubst $(sdir)/%.c,$(odir)/%.o,$(ARCH_UFTRACE_SRC))
ARCH_ATTACH_OBJS = $(patsubst $(sdir)/%.S,$(odir)/%.op,$(ARCH_ATTACH_ASM))

all: $(odir)/entry.op

$(odir)/mcount-entry.op: $(ARCH_MCOUNT_OBJS)
$(QUIET_LINK)$(LD) $(LINKFLAGS) -o $@ $^

$(odir)/uftrace.o: $(ARCH_UFTRACE_OBJS)
$(odir)/uftrace.o: $(ARCH_UFTRACE_OBJS) $(ARCH_ATTACH_OBJS)
$(QUIET_LINK)$(LD) $(LINKFLAGS) -o $@ $^

$(odir)/%.op: $(sdir)/%.S
Expand Down
94 changes: 94 additions & 0 deletions arch/x86_64/inject-content.S
@@ -0,0 +1,94 @@
#include "utils/asm.h"

.file "inject.c"
.section .data
FUNC(inject_contents_start)
END(inject_contents_start)

FUNC(inject_so_loader)
/*
* The PC of the target program is changed by uftrace to reach here
* to make load the shared object module the libmcount. uftrace use
* ptrace to do this. but sometime target program have not jump to PC
* which assigned by uftrace. there is some different between assigned
* address and real jump address. maybe it cause by ptrace inner work.
*
* [NOTICE]
* nop instructions has been added to mitigate this problem.
*/
nop
nop
nop

/*
* save registers what used in below codes
*/
pushq %rax
pushq %rsi
pushq %rdi
pushq %r9
/* create new stack frame to save registers */
pushq %rsp
pushq %rbp
movq %rsp, %rbp

/*
* since recently dlopen use movabs instruction,
* stack must be aligned by 16byte.
*/
andq $-16, %rsp

/*
* 1st argument to dlopen():
* absolute path of shared object to loaded.
*/
leaq inject_so_path(%rip), %rdi
/*
* 2nd argument
* 0x80000000 : __RTLD_DLOPEN
* 0x00000001 : RTLD_NOW
*/
movabs $0x80000001, %rsi
movq inject_dlopen_addr(%rip), %r9

/*
* call dlopen()
*/
callq *%r9

/*
* rewind stack
*/
movq %rbp, %rsp
popq %rbp
popq %rsp
/*
* restore used registers.
*/
popq %r9
popq %rdi
popq %rsi
popq %rax

/*
* return to original control flow that
* before to trapped by ptrace.
*/
jmpq *0(%rip)
END(inject_so_loader)

OBJECT(inject_so_loader_ret)
.zero 8
END(inject_so_loader_ret)

OBJECT(inject_dlopen_addr)
.zero 8
END(inject_dlopen_addr)

OBJECT(inject_so_path)
.string "absolute path of shared object"
.zero 97
END(inject_so_path)

FUNC(inject_contents_end)
END(inject_contents_end)
18 changes: 16 additions & 2 deletions arch/x86_64/mcount-arch.h
@@ -1,9 +1,23 @@
#ifndef MCOUNT_ARCH_H
#define MCOUNT_ARCH_H

#include "utils/arch.h"
#include <sys/user.h>
#include <stdbool.h>
#include "utils/list.h"

#define ARCH_REGS struct user_regs_struct
#define ARCH_PC_TYPE typeof(((ARCH_REGS *)0)->rip)

inline ARCH_PC_TYPE get_pc(ARCH_REGS regs)
{
return regs.rip;
}

inline void set_pc(ARCH_REGS *regs, ARCH_PC_TYPE pc)
{
regs->rip = pc;
}

#define mcount_regs mcount_regs

struct mcount_regs {
Expand Down Expand Up @@ -37,7 +51,7 @@ struct mcount_arch_context {
#define ARCH_CAN_RESTORE_PLTHOOK 1

struct plthook_arch_context {
bool has_plt_sec;
bool has_plt_sec;
};

struct mcount_disasm_engine;
Expand Down
1 change: 0 additions & 1 deletion arch/x86_64/mcount-dynamic.c
Expand Up @@ -11,7 +11,6 @@
#include "utils/utils.h"
#include "utils/symbol.h"

#define PAGE_SIZE 4096
#define XRAY_SECT "xray_instr_map"
#define MCOUNTLOC_SECT "__mcount_loc"

Expand Down
1 change: 0 additions & 1 deletion arch/x86_64/mcount-event.c
Expand Up @@ -11,7 +11,6 @@
#include "libmcount/internal.h"

#define INVALID_OPCODE 0xce
#define PAGE_SIZE 4096
#define PAGE_ADDR(a) ((void *)((a) & ~(PAGE_SIZE - 1)))

static void sdt_handler(int sig, siginfo_t *info, void *arg)
Expand Down