有些宏真的很绕:
static inline int
common_init (struct cursor *c, unsigned use_prev_instr)
{
int ret;
c->dwarf.loc[RAX] = REG_INIT_LOC(c, rax, RAX);
->
# define REG_INIT_LOC(c, rlc, ruc) \
DWARF_REG_LOC (&c->dwarf, UNW_X86_64_ ## ruc)
->
# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \
x86_64_r_uc_addr(dwarf_get_uc(c), (r)), 0))
->
先从最里面转:
dwarf_get_uc(c)
->
static inline ucontext_t *
dwarf_get_uc(const struct dwarf_cursor *cursor)
{
assert(cursor->as == unw_local_addr_space);
return AS_ARG_GET_UC_PTR(cursor->as_arg);
}
# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \
x86_64_r_uc_addr(cursor->as_arg, (r)), 0))
->
x86_64_r_uc_addr
#define x86_64_r_uc_addr UNW_OBJ(r_uc_addr)
UNW_OBJ(r_uc_addr) 根据平台生成对应函数名
HIDDEN void *
x86_64_r_uc_addr (ucontext_t *uc, int reg)
{
/* NOTE: common_init() in init.h inlines these for fast path access. */
void *addr;
switch (reg)
{
case UNW_X86_64_R8: addr = &uc->uc_mcontext.gregs[REG_R8]; break;
case UNW_X86_64_R9: addr = &uc->uc_mcontext.gregs[REG_R9]; break;
case UNW_X86_64_R10: addr = &uc->uc_mcontext.gregs[REG_R10]; break;
case UNW_X86_64_R11: addr = &uc->uc_mcontext.gregs[REG_R11]; break;
根据reg返回地址
最终
c->dwarf.loc[RAX] = REG_INIT_LOC(c, rax, RAX);
# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) })
等于
c->dwarf.loc[RAX] = ((dwarf_loc_t) { .val = ( &uc->uc_mcontext.gregs[REG_R8]), .type = (t) })