Adds /*<type>*/ comments and a linter check from rz-bindgen to enforce their existence and consistency Also includes the following fixes made when adding the annotations: * removed unused intern_table arguments in pyc_dis.c, pyc_dis.h, asm_pyc.c * removed unused classes argument from place_nodes in agraph.c * removed unused recurse and recurse_bb functions in canalysis.c * removed unused vars field from RzPrint struct * removed unused RzAnalysisType* structs from rz_analysis.h * removed unused list field from RzEgg struct * fixed bug in bp_plugin.c where duplication-checking logic iterates over the wrong list * removed unused q_regs field from RzDebug struct * removed unused backtrace field from RzDebugPlugin struct * removed unused classes_list field from RzBinNXOObj struct * removed unused methods_list and classes_list fields from RzBinZimgObj struct
112 lines
3.1 KiB
C
112 lines
3.1 KiB
C
// SPDX-FileCopyrightText: 2015 pancake <pancake@nopcode.org>
|
|
// SPDX-License-Identifier: LGPL-3.0-only
|
|
|
|
static RzList /*<RzDebugFrame *>*/ *backtrace_x86_64(RzDebug *dbg, ut64 at) {
|
|
int i;
|
|
ut8 buf[8];
|
|
RzDebugFrame *frame;
|
|
ut64 ptr, ebp2;
|
|
ut64 _rip, _rsp, _rbp = 0;
|
|
RzList *list;
|
|
RzReg *reg = dbg->reg;
|
|
RzIOBind *bio = &dbg->iob;
|
|
|
|
_rip = rz_reg_get_value(reg, rz_reg_get(reg, "rip", RZ_REG_TYPE_GPR));
|
|
if (at == UT64_MAX) {
|
|
_rsp = rz_reg_get_value(reg, rz_reg_get(reg, "rsp", RZ_REG_TYPE_GPR));
|
|
_rbp = rz_reg_get_value(reg, rz_reg_get(reg, "rbp", RZ_REG_TYPE_GPR));
|
|
} else {
|
|
_rsp = _rbp = at;
|
|
}
|
|
|
|
list = rz_list_new();
|
|
list->free = free;
|
|
bio->read_at(bio->io, _rip, (ut8 *)&buf, 8);
|
|
/* %rbp=old rbp, %rbp+4 points to ret */
|
|
/* Plugin before function prelude: push %rbp ; mov %rsp, %rbp */
|
|
if (!memcmp(buf, "\x55\x89\xe5", 3) || !memcmp(buf, "\x89\xe5\x57", 3)) {
|
|
if (!bio->read_at(bio->io, _rsp, (ut8 *)&ptr, 8)) {
|
|
eprintf("read error at 0x%08" PFMT64x "\n", _rsp);
|
|
rz_list_purge(list);
|
|
free(list);
|
|
return false;
|
|
}
|
|
frame = RZ_NEW0(RzDebugFrame);
|
|
frame->addr = ptr;
|
|
frame->size = 0; // TODO ?
|
|
rz_list_append(list, frame);
|
|
_rbp = ptr;
|
|
}
|
|
|
|
for (i = 1; i < dbg->btdepth; i++) {
|
|
// TODO: make those two reads in a shot
|
|
bio->read_at(bio->io, _rbp, (ut8 *)&ebp2, 8);
|
|
if (ebp2 == UT64_MAX)
|
|
break;
|
|
bio->read_at(bio->io, _rbp + 8, (ut8 *)&ptr, 8);
|
|
if (!ptr || !_rbp)
|
|
break;
|
|
frame = RZ_NEW0(RzDebugFrame);
|
|
frame->addr = ptr;
|
|
frame->size = 0; // TODO ?
|
|
rz_list_append(list, frame);
|
|
_rbp = ebp2;
|
|
}
|
|
return list;
|
|
}
|
|
// XXX: Do this work correctly?
|
|
static RzList /*<RzDebugFrame *>*/ *backtrace_x86_64_analysis(RzDebug *dbg, ut64 at) {
|
|
int i;
|
|
ut8 buf[8];
|
|
RzDebugFrame *frame;
|
|
ut64 ptr, ebp2 = UT64_MAX;
|
|
ut64 _rip, _rbp;
|
|
RzList *list;
|
|
RzReg *reg = dbg->reg;
|
|
RzIOBind *bio = &dbg->iob;
|
|
RzAnalysisFunction *fcn;
|
|
|
|
_rip = rz_reg_get_value(reg, rz_reg_get(reg, "rip", RZ_REG_TYPE_GPR));
|
|
if (at == UT64_MAX) {
|
|
//_rsp = rz_reg_get_value (reg, rz_reg_get (reg, "rsp", RZ_REG_TYPE_GPR));
|
|
_rbp = rz_reg_get_value(reg, rz_reg_get(reg, "rbp", RZ_REG_TYPE_GPR));
|
|
} else {
|
|
_rbp = at;
|
|
}
|
|
|
|
list = rz_list_new();
|
|
list->free = free;
|
|
bio->read_at(bio->io, _rip, (ut8 *)&buf, 8);
|
|
|
|
// TODO : frame->size by using esil to emulate first instructions
|
|
fcn = rz_analysis_get_fcn_in(dbg->analysis, _rip, RZ_ANALYSIS_FCN_TYPE_NULL);
|
|
if (fcn) {
|
|
frame = RZ_NEW0(RzDebugFrame);
|
|
frame->addr = _rip;
|
|
frame->size = 0;
|
|
frame->sp = _rbp;
|
|
frame->bp = _rbp + 8; // XXX
|
|
rz_list_append(list, frame);
|
|
}
|
|
|
|
for (i = 1; i < dbg->btdepth; i++) {
|
|
// TODO: make those two reads in a shot
|
|
bio->read_at(bio->io, _rbp, (ut8 *)&ebp2, 8);
|
|
if (ebp2 == UT64_MAX)
|
|
break;
|
|
bio->read_at(bio->io, _rbp + 8, (ut8 *)&ptr, 8);
|
|
if (!ptr || !_rbp)
|
|
break;
|
|
// fcn = rz_analysis_get_fcn_in (dbg->analysis, ptr, RZ_ANALYSIS_FCN_TYPE_NULL);
|
|
frame = RZ_NEW0(RzDebugFrame);
|
|
frame->addr = ptr;
|
|
frame->size = 0;
|
|
frame->sp = _rbp;
|
|
frame->bp = _rbp + 8;
|
|
// frame->name = (fcn && fcn->name) ? strdup (fcn->name) : NULL;
|
|
rz_list_append(list, frame);
|
|
_rbp = ebp2;
|
|
}
|
|
|
|
return list;
|
|
}
|