链接列表在执行期间不会复合

时间:2018-04-26 23:28:05

标签: c data-structures linked-list

我正在尝试创建一个链接列表,在解析汇编代码文件时存储返回指令。作为代码的解释,当遇到调用指令时,将保存下一条指令的地址。当遇到返回指令时,应该遍历链表,直到它到达下一个节点为if nums[i]==1 and nums[i+1]==2 and nums[i+2]==3 的点。由于某种原因,代码不保存返回地址。它可能与递归有关吗?

NULL

在初始//function to create a node in linked list struct ret_addr *return_address(cs_insn *insn, struct ret_addr *r) { struct ret_addr *ret = malloc(sizeof(*ret)); ret->address = insn->address + insn->size; ret->nxt_ret_addr = r; return ret; } //retrieve the data from the last node of the linked list int return_val(struct ret_addr *r) { if(r == NULL) return 0; while(r->nxt_ret_addr != NULL) { r = r->nxt_ret_addr; return r->address; } } //parse assembly code struct bb_data *disassemble_function_cfg(int startAddr, unsigned char *bytes, int end_section) { csh handle; cs_insn *insn; cs_detail *detail; size_t count; int stop_disasm = 0; struct ret_addr *r_data = malloc(sizeof(*r_data)); count = cs_disasm(handle, bytes, end_section, startAddr, 1, &insn); detail = insn->detail; for(int n = 0; n < detail->groups_count; n++) { if(detail->groups[n] == X86_GRP_CALL) { stop_disasm = 1; r_data = return_address(insn, r_data); } else if(detail->groups[n] == X86_GRP_RET) { stop_disasm = 1; start_edge = return_val(r_data); } if(!stop_disasm) disassemble_function_cfg(insn->address + insn->size, bytes + insn->size, end_section); else return edges; } 指令期间保存返回值(通过打印输出来检查),但是当到达返回指令时,链接列表突然变空。我的想法是,这是由call的不断调用引起的,但我不确定这是否是一个正确的假设。

1 个答案:

答案 0 :(得分:1)

问题出在return_val函数中:它不会修改调用函数r_data中的disassemble_function_cfg值。

我还假设了一件小事:因为它是一个调用/返回实现,链表应该表现为LIFO(后进先出)。 return_address函数通过插入头部来填充链接列表,因此return_val函数应首先从头部删除地址:在到达NULL之前无需读取列表。

试试这段代码:

//retrieve the data from the last node of the linked list
int return_val(struct ret_addr **r) {
    int ret_val;
    if (*r == NULL)
        return 0;
    ret_val = (*r)->address;
    *r = (*r)->nxt_ret_addr;
    return ret_val;
}

在来电者功能中:

    else if(detail->groups[n] == X86_GRP_RET) {
        stop_disasm = 1;
        start_edge = return_val(&r_data); // address of r_data, so it can be modified
    }