/* Otherwise invalidate caller-saved registers after call */ for (unsigned i = 0; i < ARRAY_SIZE(state->regs); i++) { if (state->regs[i].caller_saved)
state->regs[i].ok = false;
}
/* Update register with the return type (if any) */ if (die_find_func_rettype(cu_die, func->name, &type_die)) {
tsr = &state->regs[state->ret_reg];
tsr->type = type_die;
tsr->kind = TSR_KIND_TYPE;
tsr->ok = true;
if (get_global_var_type(cu_die, dloc, ip, imm_value, &offset,
&type_die) && offset == 0) { /* * This is not a pointer type, but it should be treated * as a pointer.
*/
tsr->type = type_die;
tsr->kind = TSR_KIND_POINTER;
tsr->ok = true;
/* Case 1. register to register or segment:offset to register transfers */ if (!src->mem_ref && !dst->mem_ref) { if (!has_reg_type(state, dst->reg1)) return;
tsr = &state->regs[dst->reg1];
tsr->copied_from = -1;
if (dso__kernel(map__dso(dloc->ms->map)) &&
src->segment == INSN_SEG_X86_GS && src->imm) {
u64 ip = dloc->ms->sym->start + dl->al.offset;
u64 var_addr; int offset;
/* * In kernel, %gs points to a per-cpu region for the * current CPU. Access with a constant offset should * be treated as a global variable access.
*/
var_addr = src->offset;
/* * In kernel, %gs points to a per-cpu region for the * current CPU. Access with a constant offset should * be treated as a global variable access.
*/ if (get_global_var_type(cu_die, dloc, ip, var_addr,
&offset, &type_die) &&
die_get_member_type(&type_die, offset, &type_die)) {
tsr->type = type_die;
tsr->kind = TSR_KIND_TYPE;
tsr->ok = true;
if (src->multi_regs) {
pr_debug_dtp("mov [%x] percpu %#x(reg%d,reg%d) -> reg%d",
insn_offset, src->offset, src->reg1,
src->reg2, dst->reg1);
} else {
pr_debug_dtp("mov [%x] percpu %#x(reg%d) -> reg%d",
insn_offset, src->offset, sreg, dst->reg1);
}
pr_debug_type_name(&tsr->type, tsr->kind);
} else {
tsr->ok = false;
}
} /* And then dereference the calculated pointer if it has one */ elseif (has_reg_type(state, sreg) && state->regs[sreg].ok &&
state->regs[sreg].kind == TSR_KIND_POINTER &&
die_get_member_type(&state->regs[sreg].type,
src->offset, &type_die)) {
tsr->type = type_die;
tsr->kind = TSR_KIND_TYPE;
tsr->ok = true;
pr_debug_dtp("mov [%x] pointer %#x(reg%d) -> reg%d",
insn_offset, src->offset, sreg, dst->reg1);
pr_debug_type_name(&tsr->type, tsr->kind);
} /* Or try another register if any */ elseif (src->multi_regs && sreg == src->reg1 &&
src->reg1 != src->reg2) {
sreg = src->reg2; goto retry;
} else { int offset; constchar *var_name = NULL;
/* it might be per-cpu variable (in kernel) access */ if (src->offset < 0) { if (get_global_var_info(dloc, (s64)src->offset,
&var_name, &offset) &&
!strcmp(var_name, "__per_cpu_offset")) {
tsr->kind = TSR_KIND_PERCPU_BASE;
tsr->ok = true;
pr_debug_dtp("mov [%x] percpu base reg%d\n",
insn_offset, dst->reg1); return;
}
}
tsr->ok = false;
}
} /* Case 3. register to memory transfers */ if (!src->mem_ref && dst->mem_ref) { if (!has_reg_type(state, src->reg1) ||
!state->regs[src->reg1].ok) return;
/* Check stack variables with offset */ if (dst->reg1 == fbreg || dst->reg1 == state->stack_reg) { struct type_state_stack *stack; int offset = dst->offset - fboff;
tsr = &state->regs[src->reg1];
stack = find_stack_state(state, offset); if (stack) { /* * The source register is likely to hold a type * of member if it's a compound type. Do not * update the stack variable type since we can * get the member type later by using the * die_get_member_type().
*/ if (!stack->compound)
set_stack_state(stack, offset, tsr->kind,
&tsr->type);
} else {
findnew_stack_state(state, offset, tsr->kind,
&tsr->type);
}
if (dst->reg1 == fbreg) {
pr_debug_dtp("mov [%x] reg%d -> -%#x(stack)",
insn_offset, src->reg1, -offset);
} else {
pr_debug_dtp("mov [%x] reg%d -> %#x(reg%d)",
insn_offset, src->reg1, offset, dst->reg1);
}
pr_debug_type_name(&tsr->type, tsr->kind);
} /* * Ignore other transfers since it'd set a value in a struct * and won't change the type.
*/
} /* Case 4. memory to memory transfers (not handled for now) */
} #endif
Messung V0.5
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.