dwarf程序

xiaoxiao2021-02-28  69

解析全局变量,函数,局部变量并按一定格式保存

点击(此处)折叠或打开

#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <errno.h> #include <string.h> #include "dwarf.h" #include "libdwarf.h" #define printf(line, ...) ; //禁用所有的printf static const char *const dwarf_regnames_i386[] = {   "eax", "ecx", "edx", "ebx",   "esp", "ebp", "esi", "edi",   "eip", "eflags", NULL,   "st0", "st1", "st2", "st3",   "st4", "st5", "st6", "st7",   NULL, NULL,   "xmm0", "xmm1", "xmm2", "xmm3",   "xmm4", "xmm5", "xmm6", "xmm7",   "mm0", "mm1", "mm2", "mm3",   "mm4", "mm5", "mm6", "mm7",   "fcw", "fsw", "mxcsr",   "es", "cs", "ss", "ds", "fs", "gs", NULL, NULL,   "tr", "ldtr" };//寄存器顺序+名字,从GDB源代码里copy过来的。。。 static const char *const dwarf_base_type[]= {     "void",     "unsigned int", "unsigned char"    ,"short unsigned int",     "long unsigned int", "signed char", "short int",     "int", "long long int", "long long unsigned int",     "long int", "char", "union", "struct" }; // 11个C基本类型 + 联合体 + 结构体 + void 没了 C就这么多了 #pragma pack(1) struct sub {     char name[8]; //函数名称     unsigned short level;//函数位于dwarf信息的第几层     unsigned char type;//返回值类型,对应dwarf_base_type结构     unsigned int low_pc;//函数的起始地址     unsigned int high_pc;//函数的结束地址     struct loc *loc;//函数执行期间寄存器偏移信息     struct var *var;//函数内的变量信息     struct sub *next;//指向下一个sub结构的单链表 }; struct loc {     unsigned int begin;//偏移开始地址     unsigned int end;//偏移结束地址     unsigned char reg;// *data -0x70 对应上面的寄存器表 其实X86 -O0编译也就4、5两个值     unsigned short base; // *(data+1)便宜值     struct loc *next;//指向下一个loc结构的单链表 }; struct var {     char name[8];//变量名字     unsigned int array; // 数组长度,0表示不是数组     unsigned char points; //这个变量是几层指针     unsigned char type; //变量类型,对应dwarf_base_type结构     unsigned int len;//变量类型长度     unsigned char loc_type; //变量地址类型     unsigned int loc;//变量地址数据,具体含义由loc_type确定     struct var *next;//指向下一个var结构的单链表 }; struct info {     struct sub * sub_link;//解析过程保存函数链表     struct var * global;//解析过程中保存全局变量链表 }; #pragma pack() struct info asd; ///// 在内存中以链表形式保存提取到的信息 unsigned int cu_low_pc;//当前正在处理的编译单元的起始地址 int is_new_cu;//进入新的编译单元 /*******************************************************************************   *函数名称:static void get_addr(Dwarf_Attribute attr, Dwarf_Addr *val)   *函数功能:提取直接地址类型属性条目中保存的地址   *输入参数:     @Dwarf_Attribute attr:地址类型属性条目   *输出参数:     @Dwarf_Addr *val:条目中包含的地址   *函数返回值:无   *其他: *******************************************************************************/ static void get_addr(Dwarf_Attribute attr, Dwarf_Addr *val) {     Dwarf_Error error = 0;     int res;     Dwarf_Addr uval = 0;     res = dwarf_formaddr(attr, &uval, &error);     if (res == DW_DLV_OK)         *val = uval; } /*******************************************************************************   *函数名称:static struct sub *new_sub(char* name,unsigned int low,unsigned int high)   *函数功能:申请一个函数信息块内存空间,并赋值   *输入参数:     @char* name:函数的名称     @unsigned int low:函数的起始地址     @unsigned int high:函数的结束地址   *输出参数:无   *函数返回值:struct sub *:申请的信息块地址   *其他: *******************************************************************************/ static struct sub *new_sub(char* name,unsigned int low,unsigned int high) {     struct sub *tmp_sub = NULL;     tmp_sub = (struct sub*) malloc(sizeof(struct sub));//申请地址     if(tmp_sub)//成功的话,填充结构体信息     {         memset(tmp_sub,0,sizeof(struct sub));         if(name)             memcpy(tmp_sub->name,name,strlen(name)>8?8:strlen(name));         tmp_sub->low_pc = low;         tmp_sub->high_pc = high;         return tmp_sub;     }     else//失败返回空         return NULL; } /*******************************************************************************   *函数名称:static void get_loc_list(Dwarf_Debug dbg, Dwarf_Die die, struct sub *sub)   *函数功能:解析一个函数类型die的下挂的寄存器偏移信息,保存到sub->loc链表中   *输入参数:     @Dwarf_Debug dbg:libdwarf库的总数据结构     @Dwarf_Die die:需要被解析的一个函数类型die     @struct sub *sub:函数DIE对应的信息块指针   *输出参数:无   *函数返回值:无   *其他:dwarf_ 开头的函数都是libdwarf库提供的函数 *******************************************************************************/ static void get_loc_list(Dwarf_Debug dbg, Dwarf_Die die, struct sub *sub) {     Dwarf_Unsigned offset=0;     Dwarf_Error error = 0;     Dwarf_Addr hipc_off;     Dwarf_Addr lopc_off;     Dwarf_Ptr data;     Dwarf_Unsigned entry_len;     Dwarf_Error err;     int res;     Dwarf_Unsigned next_entry;     Dwarf_Attribute t_attr;     struct loc *tmp=NULL,*pos;     res = dwarf_attr(die, DW_AT_frame_base, &t_attr, &error);//使用libdwarf库解析条目属性     if (res == DW_DLV_OK)     {         res = dwarf_formudata(t_attr, &offset, &error);//使用libdwarf库获取属性对应的条目链         if (res == DW_DLV_OK)             for(;;)                 {                     res = dwarf_get_loclist_entry(dbg,offset,&hipc_off,&lopc_off,&data,&entry_len,&next_entry,&err);//遍历所有条目                     if (res == DW_DLV_OK)                     {//每成功取出一个条目                         if(entry_len == 0 )                             break;                         if(entry_len > 1 )                         {                         tmp = (struct loc*) malloc(sizeof(struct loc));//申请内存                         if(tmp)                         {                             memset(tmp,0,sizeof(struct loc));                             tmp ->begin = cu_low_pc + lopc_off;                             tmp ->end = cu_low_pc + hipc_off;                             tmp ->reg = (unsigned short)*(char*)data;//保存条目信息                             if(entry_len == 2)                                 tmp ->base = (unsigned short)*(char *)(data+1);                             else                                 tmp ->base = (unsigned short)*(unsigned short *)(data+1);                             if(sub->loc)                             {                                 pos = sub->loc;//加入当前处理的函数的loc链表中                                 while(pos->next)                                     pos = pos->next;                                 pos->next = tmp;                             }                             else                                 sub->loc = tmp;                         }                         else break;                         }                         offset = next_entry;                         continue;                     }                     else break;                 }     } } /*******************************************************************************   *函数名称:static Dwarf_Die get_die(Dwarf_Debug dbg, Dwarf_Attribute attr, Dwarf_Half* tag)   *函数功能:通过偏移量取die和对应的标签   *输入参数:     @Dwarf_Debug dbg:libdwarf库的总数据结构     @Dwarf_Attribute attr:需要被操作的属性结构     @Dwarf_Half* tag:偏移值   *输出参数:无   *函数返回值:Dwarf_Die:找到的DIE的指针   *其他:dwarf_ 开头的函数都是libdwarf库提供的函数 *******************************************************************************/ static Dwarf_Die get_die(Dwarf_Debug dbg, Dwarf_Attribute attr, Dwarf_Half* tag) {//通过偏移量取die和对应的标签     Dwarf_Error error = 0;     int res;     Dwarf_Off offset;     Dwarf_Die typeDie = 0;     res = dwarf_global_formref(attr, &offset, &error);     if (res == DW_DLV_OK) {         res = dwarf_offdie(dbg, offset, &typeDie, &error);         if (res == DW_DLV_OK) {             res = dwarf_tag(typeDie, tag, &error);             if (res == DW_DLV_OK) {                 return typeDie;             }         }     }     return NULL ; } /*******************************************************************************   *函数名称:static void print_subprog(Dwarf_Debug dbg, Dwarf_Die die, struct sub **tmp_sub)   *函数功能:解析一个函数类型die的全部信息,保存到tmp_sub中   *输入参数:     @Dwarf_Debug dbg:libdwarf库的总数据结构     @Dwarf_Die die:需要被解析的一个函数类型die   *输出参数:     @struct sub **tmp_sub:返回函数信息块指针   *函数返回值:无   *其他:*******************************************************************************/ static void print_subprog(Dwarf_Debug dbg, Dwarf_Die die, struct sub **tmp_sub) {     int res;     Dwarf_Error error = 0;     Dwarf_Addr lowpc = 0;     Dwarf_Addr highpc = 0;     Dwarf_Attribute t_attr;     Dwarf_Half tag;     Dwarf_Die org_die = NULL;     char *name;     res = dwarf_attr(die, DW_AT_abstract_origin, &t_attr, &error);     if (res == DW_DLV_OK)         org_die = get_die(dbg, t_attr, &tag);     else org_die = die;     res = dwarf_diename(org_die, &name, &error);//获取函数的名称     if (res != DW_DLV_OK) {         name = NULL;     }     res = dwarf_attr(die, DW_AT_low_pc, &t_attr, &error);     if (res == DW_DLV_OK) // 获取函数的开始地址         get_addr(t_attr, &lowpc);     res = dwarf_attr(die, DW_AT_high_pc, &t_attr, &error);     if (res == DW_DLV_OK) // 获取函数的结束地址         get_addr(t_attr, &highpc);     *tmp_sub = new_sub(name,(unsigned int)lowpc,(unsigned int)highpc);//申请新的sub结构     //目前只考虑32位的,unsigned int就行     //} } /*******************************************************************************   *函数名称:static int get_array_length(Dwarf_Debug dbg, Dwarf_Die die, int *length)   *函数功能:计算一个数组属性的DIE对应的数组的具体长度   *输入参数:     @Dwarf_Debug dbg:libdwarf库的总数据结构     @Dwarf_Die die:需要被计算的die   *输出参数:     @int *length:返回长度值   *函数返回值:无   *其他: *******************************************************************************/ static int get_array_length(Dwarf_Debug dbg, Dwarf_Die die, int *length) {//数组类型的长度。。     int res;     Dwarf_Error error;     Dwarf_Die child;     Dwarf_Attribute tmp;     res = dwarf_child(die, &child, &error);     *length = 1;     Dwarf_Unsigned utmp;     if (res == DW_DLV_OK) {         while (1) {             res = dwarf_attr(child, DW_AT_upper_bound, &tmp, &error);             if (res == DW_DLV_OK) {                 res = dwarf_formudata(tmp, &utmp, &error);                 if (res != DW_DLV_OK)                     return DW_DLV_ERROR;                 else                     *length *= (u管理文章tmp + 1);             }             res = dwarf_siblingof(dbg, child, &child, &error);             if (res == DW_DLV_ERROR)                 return DW_DLV_ERROR;             if (res == DW_DLV_NO_ENTRY)                 return DW_DLV_OK;         }     }     return DW_DLV_ERROR; } /*******************************************************************************   *函数名称:static void get_type(Dwarf_Debug dbg, Dwarf_Attribute attr, unsigned int *arr, unsigned short *points, unsigned short *type, unsigned int *type_len)   *函数功能:解析一个变量类型描述类型die的全部信息   *输入参数:     @Dwarf_Debug dbg:libdwarf库的总数据结构     @DDwarf_Attribute attr:需要被解析的一个变量类型die   *输出参数:     @unsigned int *arr:是否是数组类型,以及数组长度     @unsigned short *points:是否时指针类型,以及指针深度,和arr同时非0,表明是一个指针数组,目前不考虑这种情况     @unsigned short *type:具体类型值,定义对应最上面dwarf_base_type数组     @unsigned int *type_len:类型长度   *函数返回值:无   *其他:具体参见DWARF Debugging Information Format.pdf文档中“类型条目”书签标记的位置        简单来说,attr是个类型描述的开头,他指向一个属性链条,每个点上保存一个属性,便利这个链条确定最终的类型 *******************************************************************************/ static void get_type(Dwarf_Debug dbg, Dwarf_Attribute attr, unsigned int *arr, unsigned short *points, unsigned short *type, unsigned int *type_len) {     char *name = 0;     Dwarf_Half tag;     Dwarf_Unsigned size;     Dwarf_Error error = 0;     Dwarf_Attribute t_attr;     int res;     int length;     Dwarf_Die typeDie = get_die(dbg, attr, &tag);     if (typeDie) {         switch (tag) {//只处理了和标准C相关的类型         case DW_TAG_subroutine_type://函数指针,对比没意义,就不管了             *type = 255;             break;         case DW_TAG_typedef://对应C语言中typedef关键字             goto next_type;         case DW_TAG_const_type://对应C语言中const关键字             goto next_type;         case DW_TAG_pointer_type://对应C语言中变量定义中的 * 指针符             *points += 1;             goto next_type;         case DW_TAG_volatile_type://对应C语言中volatile关键字             next_type: res = dwarf_attr(typeDie, DW_AT_type, &t_attr, &error);             if (res == DW_DLV_OK) {                 get_type(dbg, t_attr, arr, points, type, type_len);             } else                 *type = 1;             break;         case DW_TAG_base_type://对应dwarf_base_type定义的C基本变量类型             res = dwarf_diename(typeDie, &name, &error);             if (res == DW_DLV_OK) {                 for(res = 0;res<sizeof(dwarf_base_type)/sizeof(char *);res++)                     if(!strncmp(name,dwarf_base_type[res],strlen(dwarf_base_type[res])))                     {                         *type = res+1;                         break;                     }                 res = dwarf_bytesize(typeDie, &size, &error);                 if (res == DW_DLV_OK) {                     *type_len = ((unsigned int)size);                 } else                     *type_len = 0;             } else                 *type = 0;             break;         case DW_TAG_array_type://对应C语言中的数组定义             res = get_array_length(dbg, typeDie, &length);             if (res == DW_DLV_OK)                 *arr = length;             goto next_type;         case DW_TAG_union_type://对应C语言中联合体定义             *type = sizeof(dwarf_base_type)/sizeof(char *) -1;             goto get_size;         case DW_TAG_structure_type://对应C语言中结构体定义             *type = sizeof(dwarf_base_type)/sizeof(char *);             get_size: res = dwarf_bytesize(typeDie, &size, &error);             if (res == DW_DLV_OK)                 *type_len = (unsigned int)size;             else                 *type_len = 0;             break;         default://非C语言类型             *type = 0;             break;         }     } } /*******************************************************************************   *函数名称:static void get_location(Dwarf_Debug dbg, Dwarf_Attribute attr, unsigned int *loc_type, unsigned int *loc)   *函数功能:解析一个地址类型die的全部信息   *输入参数:     @Dwarf_Debug dbg:libdwarf库的总数据结构     @Dwarf_Attribute attr:需要被解析的一个地址类型die   *输出参数:     @unsigned int *loc_type:返回die标签包含的地址的地址类型     @unsigned int *loc:返回die标签包含的地址的具体地址数值   *函数返回值:无   *其他:地址类型和地址数值包含[直接地址:32位线性地址][寄存器基址寻址:偏移值]等多个可能的赋值含义组合      具体参见DWARF Debugging Information Format.pdf文档中“位置描述”书签标记的位置 *******************************************************************************/ static void get_location(Dwarf_Debug dbg, Dwarf_Attribute attr, unsigned int *loc_type, unsigned int *loc) {     Dwarf_Error error = 0;     int res;     Dwarf_Locdesc *llbuf;     Dwarf_Signed lcnt;     res = dwarf_loclist(attr, &llbuf, &lcnt, &error);     if (res == DW_DLV_OK) {         *loc_type = (unsigned int) llbuf->ld_s->lr_atom;         *loc = (unsigned int)llbuf->ld_s->lr_number;         dwarf_dealloc(dbg, llbuf->ld_s, DW_DLA_LOC_BLOCK);         dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC);     } } /*******************************************************************************   *函数名称:static void print_variable(Dwarf_Debug dbg, Dwarf_Die die, struct var ** tmp_loc)   *函数功能:解析一个变量类型die的全部信息,保存到tmp_loc中   *输入参数:     @Dwarf_Debug dbg:libdwarf库的总数据结构     @Dwarf_Die die:需要被解析的一个变量类型die   *输出参数:     @struct var ** tmp_loc:返回变量信息块指针   *函数返回值:无   *其他:*******************************************************************************/ static void print_variable(Dwarf_Debug dbg, Dwarf_Die die, struct var ** tmp_loc) {     int res;     Dwarf_Error error = 0;     Dwarf_Attribute t_attr;     unsigned int arr, type_len, loc_type, loc;     unsigned short points, type ;     struct var * tmp =NULL ;     Dwarf_Die org_die = NULL;     Dwarf_Half tag;     char *name;     *tmp_loc = tmp;     res = dwarf_attr(die, DW_AT_abstract_origin, &t_attr, &error);     if (res == DW_DLV_OK)         org_die = get_die(dbg, t_attr, &tag);     else org_die = die;     res = dwarf_diename(org_die, &name, &error);     if (res != DW_DLV_OK) {         name = NULL;     }     res = dwarf_attr(die, DW_AT_declaration, &t_attr, &error);     if (res != DW_DLV_OK) { //若res == DW_DLV_OK,则是extern变量,没有位置信息,就不再保存         loc_type = loc =0;         arr = type_len = 0;         points = type = 0;         res = dwarf_attr(die, DW_AT_location, &t_attr, &error);         if (res == DW_DLV_OK) //获取变量的位置信息             get_location(dbg, t_attr, &loc_type, &loc);         if(loc_type == 0)         {             printf("no loc info !!\n");             return;         }         res = dwarf_attr(org_die, DW_AT_type, &t_attr, &error);         if (res == DW_DLV_OK) // 确定变量的类型以及长度             get_type(dbg, t_attr, &arr, &points, &type, &type_len);         if(type == 0)         {             printf("error in get_type \n ");             return;         }         if(type == 255)         {             printf("DW_TAG_subroutine_type !! \n");             return;         }         tmp = (struct var*) malloc(sizeof(struct var));//申请新的var结构体存放变量信息         if (tmp)         {             memset(tmp,0,sizeof(struct var));             if(name)                 memcpy(tmp->name,name,strlen(name)>8?8:strlen(name));             tmp->array = arr;             tmp->points = points;             tmp->type = type;             tmp->len = type_len;             tmp->loc_type = loc_type;             tmp->loc = loc;             *tmp_loc = tmp;         }     } } /*******************************************************************************   *函数名称:static void get_die_and_siblings(Dwarf_Debug dbg, Dwarf_Die in_die,int in_level)   *函数功能:递归遍历整个DWARF调试信息树,取出其中的变量、寄存器偏移和变量信息   *输入参数:     @Dwarf_Debug dbg:libdwarf库的总数据结构     @Dwarf_Die in_die:需要被遍历的头一个die     @int in_level:便利处于第几层   *输出参数:无   *函数返回值:无   *其他:*******************************************************************************/ static void get_die_and_siblings(Dwarf_Debug dbg, Dwarf_Die in_die,         int in_level) {     int res = DW_DLV_ERROR;     Dwarf_Die cur_die = in_die;     Dwarf_Die child = 0;     Dwarf_Error error;     Dwarf_Half tag;     Dwarf_Attribute t_attr;     Dwarf_Unsigned inline_tag;     Dwarf_Die sib_die = 0;     struct var *t_var , *p_var;     struct sub *t_sub , *p_sub;     struct todo     {         Dwarf_Die d;         Dwarf_Half tag;         struct todo *n;     }*todo_list,*t_todo,*p_todo;     todo_list = NULL;     for(;;)     {         res = dwarf_tag(cur_die, &tag, &error); // 取标签         if (res != DW_DLV_OK) {             printf("Error in dwarf_tag , level %d \n", in_level);             exit(1);         }         if(in_level == 1) //由于标准C不允许函数嵌套定义,SO ,1层只有全局变量和函数顶层         {             if(tag == DW_TAG_variable) //全局变量             {                 print_variable(dbg, cur_die, &t_var);                 if(asd.global) //放进全局链结尾去                 {                     p_var = asd.global;                     while(p_var->next)                         p_var = p_var->next;                     p_var->next = t_var;                 }                 else                     asd.global = t_var;             }             if(tag == DW_TAG_subprogram) //函数,判断是否时inline 然后加进SUB链 然后进child取局部变量和包含的块和inlined             {                 res = dwarf_attr(cur_die, DW_AT_inline, &t_attr, &error);                 if(res == DW_DLV_OK)                 {                     res = dwarf_formudata(t_attr, &inline_tag, &error);                     if(res != DW_DLV_OK)                         exit(1);                     if(inline_tag == DW_INL_inlined || inline_tag == DW_INL_declared_inlined)                         goto next_sib;//是inline函数 就出去继续循环 后面把非inline函数加进SUB                 }                 print_subprog(dbg, cur_die, &t_sub);                 if(t_sub)                 {                     if(is_new_cu)                     {                         is_new_cu = 0;                         cu_low_pc = t_sub->low_pc;                     }                     t_sub->level = in_level;                     t_sub->type = DW_TAG_subprogram;                     get_loc_list(dbg, cur_die, t_sub); //把loc信息添加进去                     if(asd.sub_link) //放进sub链结尾去                     {                         p_sub = asd.sub_link;                         while(p_sub->next)                             p_sub = p_sub->next;                         p_sub->next = t_sub;                     }                     else                         asd.sub_link = t_sub;                     res = dwarf_child(cur_die, &child, &error);                     if (res == DW_DLV_ERROR)                     {                         printf("Error in dwarf_child , level %d \n", in_level);                         exit(1);                     }                     if (res == DW_DLV_OK)                         get_die_and_siblings(dbg, child, in_level + 1); //进入child 也就是>1的层                 }             }         }         else if(in_level > 1) //大于1层的地方只有局部变量和块、inlined         {             if (tag == DW_TAG_formal_parameter || tag == DW_TAG_variable) //局部变量,挂到sub链最后一个的VAR指针上             {                 print_variable(dbg, cur_die, &t_var);                 p_sub = asd.sub_link;                 while(p_sub->next)                     p_sub = p_sub->next;                 if(p_sub->var)                 {                     p_var = p_sub->var;                     while(p_var->next)                         p_var = p_var->next;                     p_var->next = t_var;                 }                 else                     p_sub->var = t_var;             }             if(tag == DW_TAG_lexical_block || tag == DW_TAG_inlined_subroutine) // 先放到todo_list里面在for外面单独处理             {                 t_todo = (struct todo *) malloc(sizeof(struct todo));                 if(t_todo)                 {                     memset(t_todo,0,sizeof(struct todo));                     t_todo->d = cur_die;                     t_todo->tag = tag;                     if(todo_list)                     {                         p_todo = todo_list;                         while(p_todo->n)                             p_todo = p_todo->n;                         p_todo->n = t_todo;                     }                     else                         todo_list = t_todo;                 }             }         }         else         {//0层是变编译头信息,没啥用就直接进child             res = dwarf_child(cur_die, &child, &error);             if (res == DW_DLV_ERROR)             {                 printf("Error in dwarf_child , level %d \n", in_level);                 exit(1);             }             if (res == DW_DLV_OK)             {                 is_new_cu = 1;                 get_die_and_siblings(dbg, child, in_level + 1);             }         }         next_sib:         sib_die = 0;         res = dwarf_siblingof(dbg, cur_die, &sib_die, &error);         if (res == DW_DLV_ERROR) {             printf("Error in dwarf_siblingof , level %d \n", in_level);             exit(1);         }         if (res == DW_DLV_NO_ENTRY)             break;         if (cur_die != in_die && in_level < 2)             dwarf_dealloc(dbg, cur_die, DW_DLA_DIE);         cur_die = sib_die;     }     if(todo_list)     {         t_todo = p_todo = todo_list;         todo_list = NULL;         while(p_todo)         {             print_subprog(dbg, p_todo->d, &t_sub);             if(t_sub)             {                 t_sub->level = in_level;                 t_sub->type = p_todo->tag;                 if(asd.sub_link) //放进sub链结尾去                 {                     p_sub = asd.sub_link;                     while(p_sub->next)                         p_sub = p_sub->next;                     p_sub->next = t_sub;                 }                 else                     exit(1); //若在这里asd.sub_link依然为空,那么肯定是有错误了,因为只有在>1的时候才能进到这里                 res = dwarf_child(cur_die, &child, &error);                 if (res == DW_DLV_ERROR)                 {                     printf("Error in dwarf_child , level %d \n", in_level);                     exit(1);                 }                 if (res == DW_DLV_OK)                     get_die_and_siblings(dbg, child, in_level + 1); //进入child             }             p_todo = p_todo->n;             dwarf_dealloc(dbg, t_todo->d , DW_DLA_DIE);             free(t_todo);             t_todo = p_todo;         }     } } /*******************************************************************************   *函数名称:static void read_cu_list(Dwarf_Debug dbg)   *函数功能:遍历调试信息中包含的全部CU头,提取其中的信息   *输入参数:     @Dwarf_Debug dbg:libdwarf库的总数据结构   *输出参数:无   *函数返回值:无   *其他:*******************************************************************************/ static void read_cu_list(Dwarf_Debug dbg) {//一次取出一个CU头     Dwarf_Unsigned cu_header_length = 0;     Dwarf_Half version_stamp = 0;     Dwarf_Unsigned abbrev_offset = 0;     Dwarf_Half address_size = 0;     Dwarf_Unsigned next_cu_header = 0;     Dwarf_Error error;     for (;;) {         Dwarf_Die no_die = 0;         Dwarf_Die cu_die = 0;         int res = DW_DLV_ERROR;         res = dwarf_next_cu_header(dbg, &cu_header_length, &version_stamp,                 &abbrev_offset, &address_size, &next_cu_header, &error);//取出一个CU         if (res == DW_DLV_ERROR) {             printf("Error in dwarf_next_cu_header\n");             exit(1);         }         if (res == DW_DLV_NO_ENTRY) {             /* Done. */             return;         }         /* The CU will have a single sibling, a cu_die. */         res = dwarf_siblingof(dbg, no_die, &cu_die, &error);         if (res == DW_DLV_ERROR) {             printf("Error in dwarf_siblingof on CU die \n");             exit(1);         }         if (res == DW_DLV_NO_ENTRY) {             /* Impossible case. */             printf("no entry! in dwarf_siblingof on CU die \n");             exit(1);         }         get_die_and_siblings(dbg, cu_die, 0);//拿到CU后,进入第0层,开始递归遍历         dwarf_dealloc(dbg, cu_die, DW_DLA_DIE);     } } /*******************************************************************************   *函数名称:static void save_to_file(char *path, struct info *asd)   *函数功能:将全局链表中存放的调试信息保存到文件中   *输入参数:     @char *path:保存文件的路径     @struct info *asd:要保存的信息所在的链表   *输出参数:无   *函数返回值:无   *其他:*******************************************************************************/ static void save_to_file(char *path, struct info *asd) {     FILE * f ,* fpos;     char buf[255];     static const int size[] =     {             sizeof(struct sub) - 3 * sizeof(void *),             sizeof(struct loc) - sizeof(void *),             sizeof(struct var) - sizeof(void *)     };     static const unsigned char tag[] =     {             0x00,0x01,0x02,0x03     };     struct sub *p_sub_1, *p_sub_2;     struct loc *p_loc_1, *p_loc_2;     struct var *p_var_1, *p_var_2;     unsigned int pos;     pos = 0;     sprintf(buf,"%s.pos",path);//索引文件文件名     f = fopen(path,"w");//打开调试信息文件     fpos = fopen(buf,"w");//打开索引文件     if(f)     {         p_var_1 = asd->global;         while(p_var_1)         {//首先保存全局变量信息到调试信息文件             fwrite(tag+3, 1, 1, f);             fwrite(p_var_1, size[2], 1, f);             fwrite(tag, 1, 1, f);             p_var_2 = p_var_1;             p_var_1 = p_var_1->next;             free(p_var_2);             pos += size[2] + 2;         }         fwrite(&pos,4,1,fpos);//记录全局变量信息长度到索引文件         asd->global = NULL;         p_sub_1 = asd->sub_link;         while(p_sub_1)         {//保存变量信息             fwrite(tag+1, 1, 1, f);             fwrite(p_sub_1, size[0], 1, f);             fwrite(tag, 1, 1, f);             fwrite(&p_sub_1->low_pc, sizeof(long), 1, fpos);//函数的开始地址写入索引文件             fwrite(&p_sub_1->high_pc, sizeof(long), 1, fpos);//函数的解释地址写入索引文件             fwrite(&pos,4,1,fpos);//函数在调试信息文件中的位置,写入索引文件             pos += size[0] + 2;             p_loc_1 = p_sub_1->loc;             while(p_loc_1)             {//变量执行期间寄存偏移情况                 fwrite(tag+2, 1, 1, f);                 fwrite(p_loc_1, size[1], 1, f);                 fwrite(tag, 1, 1, f);                 p_loc_2 = p_loc_1;                 p_loc_1 = p_loc_1->next;                 free(p_loc_2);                 pos += size[1] + 2;             }             p_var_1 = p_sub_1->var;             while(p_var_1)             {//函数的局部变量                 fwrite(tag+3, 1, 1, f);                 fwrite(p_var_1, size[2], 1, f);                 fwrite(tag, 1, 1, f);                 p_var_2 = p_var_1;                 p_var_1 = p_var_1->next;                 free(p_var_2);                 pos += size[2] + 2;             }             p_sub_2 = p_sub_1;             p_sub_1 = p_sub_1->next;             free(p_sub_2);         }         asd->sub_link = NULL;         fclose(f);//关闭,完成         fclose(fpos);     } } /*//一些测试函数 static void read_from_file(char *path, struct info *asd) {//读取出来看文件是否正确     FILE * f;     static const int size[] =     {             sizeof(struct sub) - 3 * sizeof(void *),             sizeof(struct loc) - sizeof(void *),             sizeof(struct var) - sizeof(void *)     };     struct sub *p_sub_1, *p_sub_2;     struct loc *p_loc_1, *p_loc_2;     struct var *p_var_1, *p_var_2;     char t;     int is_global = 1;     f = fopen(path,"r");     if(f)     {         while(!feof(f))         {             fread(&t, 1, 1, f);             switch(t)             {             case 3:                 p_var_2 = (struct var *) malloc(sizeof(struct var));                 if(p_var_2)                 {                     memset(p_var_2, 0, sizeof(struct var));                     fread(p_var_2, size[2], 1, f);                     if(is_global)                     {                         if(asd->global)                         {                             p_var_1 = asd->global;                             while(p_var_1 ->next)                                 p_var_1 = p_var_1->next;                             p_var_1->next = p_var_2;                         }                         else                             asd->global = p_var_2;                     }                     else                     {                         p_sub_1 = asd->sub_link;                         while(p_sub_1->next)                             p_sub_1 = p_sub_1->next;                         if(p_sub_1->var)                         {                             p_var_1 = p_sub_1->var;                             while(p_var_1 ->next)                                 p_var_1 = p_var_1->next;                             p_var_1->next = p_var_2;                         }                         else                             p_sub_1->var = p_var_2;                     }                 }                 break;             case 1:                 p_sub_2 = (struct sub *) malloc(sizeof(struct sub));                 if(p_sub_2)                 {                     is_global = 0;                     memset(p_sub_2, 0, sizeof(struct sub));                     fread(p_sub_2, size[0], 1, f);                     if(asd->sub_link)                     {                         p_sub_1 = asd->sub_link;                         while(p_sub_1->next)                             p_sub_1 = p_sub_1->next;                         p_sub_1->next = p_sub_2;                     }                     else                         asd->sub_link = p_sub_2;                 }                 break;             case 2:                 p_loc_2 = (struct loc *) malloc(sizeof(struct loc));                 if(p_loc_2)                 {                     memset(p_loc_2, 0, sizeof(struct loc));                     fread(p_loc_2, size[1], 1, f);                     if(!asd->sub_link)                         exit(1);                     p_sub_1 = asd->sub_link;                     while(p_sub_1->next)                         p_sub_1 = p_sub_1->next;                     if(p_sub_1->loc)                     {                         p_loc_1 = p_sub_1->loc;                         while(p_loc_1 ->next)                             p_loc_1 = p_loc_1->next;                         p_loc_1->next = p_loc_2;                     }                     else                         p_sub_1->loc = p_loc_2;                 }                 break;             }             fread(&t, 1, 1, f);             if(t)                 exit(1);         }     } } static void print_pos(char *path) {//打印索引     FILE * f ,* fp;     char buf[255], *b,name[9];     unsigned int *bp;     int s,sp,pos;     sprintf(buf,"%s.pos",path);     f = fopen(path,"r");     fp = fopen(buf,"r");     fseek(f,0,2);     fseek(fp,0,2);     s = ftell(f);     sp = ftell(fp);     b = (char *) malloc(s);     bp = (unsigned int *) malloc(sp);     fseek(f,0,0);     fseek(fp,0,0);     fread(b,s,1,f);     fread(bp,s,1,fp);     fclose(f);     fclose(fp);     printf("全局比啊两数据长度:%d\n",*bp);     pos = 1;     while(pos < sp/4)     {         printf("low: x\n",*(bp+pos));         printf("hig: x\n",*(bp+pos+1));         memset(name,0,9);         memcpy(name,b+*(bp+pos+2)+1,8);         printf("name:%s\n",name);         pos+=3;     } } static void print(struct info asd) {//打印全部保存的调试信息     struct sub *p_sub_1;     struct loc *p_loc_1;     struct var *p_var_1;     char n[9];     p_var_1 = asd.global;     while(p_var_1)     {         memset(n,0,9);         memcpy(n,p_var_1->name,8);         printf("< 1 > 变量名: %s\n< 1 > ",n);         if ( DW_OP_addr == p_var_1->loc_type)             printf("直接地址: %x \n",(int) p_var_1->loc);         else if(p_var_1->loc_type >= DW_OP_breg0 && p_var_1->loc_type <= DW_OP_breg31)             printf("基址寻址: %d (%s)\n", ((int)p_var_1->loc), *(dwarf_regnames_i386+p_var_1->loc_type-DW_OP_breg0));         else if(p_var_1->loc_type >= DW_OP_reg0 && p_var_1->loc_type <= DW_OP_reg31)             printf("通用寄存器: reg%d \n",p_var_1->loc - DW_OP_reg0);         else if(p_var_1->loc_type == DW_OP_fbreg)             printf("loclist: %d \n",((int)p_var_1->loc));         else             printf("Unknow location \n");//不是C的不管丫的         printf("< %d > 数组: %d\n",1,p_var_1->array);         printf("< %d > 指针: %d\n",1,p_var_1->points);         printf("< %d > 类型: %s\n",1,dwarf_base_type[p_var_1->type - 1]);         printf("< 1 > 大小: %d\n\n",p_var_1->len);         p_var_1 = p_var_1->next;     }     p_sub_1 = asd.sub_link;     while(p_sub_1)     {         p_loc_1 = p_sub_1->loc;         p_var_1 = p_sub_1->var;         memset(n,0,9);         memcpy(n,p_sub_1->name,8);         printf("< %d >函数名: %s\n",p_sub_1->level,p_sub_1->type == DW_TAG_subprogram?n:"局部块");         printf("< %d >low_pc : 0xx \n",p_sub_1->level,p_sub_1->low_pc);         printf("< %d >high_pc : 0xx \n\n",p_sub_1->level,p_sub_1->high_pc);         while(p_loc_1)         {             printf("< %d > loclist: 0xx -- 0xx : (%s) %d \n",p_sub_1->level,p_loc_1->begin,p_loc_1->end,*(dwarf_regnames_i386+(p_loc_1->reg>0x70?p_loc_1->reg-0x70:10)),p_loc_1->base);             p_loc_1 = p_loc_1->next;         }         while(p_var_1)         {             memset(n,0,9);             memcpy(n,p_var_1->name,8);             printf("\n< %d > 变量名: %s\n< %d > ",p_sub_1->level+1,n,p_sub_1->level+1);             if ( DW_OP_addr == p_var_1->loc_type)                 printf("直接地址: %x \n",(int) p_var_1->loc);             else if(p_var_1->loc_type >= DW_OP_breg0 && p_var_1->loc_type <= DW_OP_breg31)                 printf("基址寻址: %d (%s)\n", ((int)p_var_1->loc), *(dwarf_regnames_i386+p_var_1->loc_type-DW_OP_breg0));             else if(p_var_1->loc_type >= DW_OP_reg0 && p_var_1->loc_type <= DW_OP_reg31)                 printf("通用寄存器: reg%d \n",p_var_1->loc - DW_OP_reg0);             else if(p_var_1->loc_type == DW_OP_fbreg)                 printf("loclist: %d \n",((int)p_var_1->loc));             else                 printf("Unknow location \n");//不是C的不管丫的             printf("< %d > 数组: %d\n",p_sub_1->level+1,p_var_1->array);             printf("< %d > 指针: %d\n",p_sub_1->level+1,p_var_1->points);             printf("< %d > 类型: %s\n",p_sub_1->level+1,dwarf_base_type[p_var_1->type - 1]);             printf("< %d > 大小: %d\n\n",p_sub_1->level+1,p_var_1->len);             p_var_1 = p_var_1->next;         }         p_sub_1 = p_sub_1->next;     } } */ int main(int argc, char **argv) {//初始化dbg     Dwarf_Debug dbg = 0;     int fd = -1;     const char *filepath = "<stdin>";     char p[255];     int res = DW_DLV_ERROR;     Dwarf_Error error;     Dwarf_Handler errhand = 0;     Dwarf_Ptr errarg = 0;     if (argc < 2)         fd = 0;     else     {         filepath = argv[1];         fd = open(filepath, O_RDONLY);     }     if (fd <= 0)     {         printf("Failure attempting to open \"%s\"\n", filepath);         exit(1);     }     res = dwarf_init(fd, DW_DLC_READ, errhand, errarg, &dbg, &error);     if (res != DW_DLV_OK) {         printf("Giving up, cannot do DWARF processing\n");         exit(1);     }     read_cu_list(dbg);//解析工作     res = dwarf_finish(dbg, &error);     if (res != DW_DLV_OK) {         printf("dwarf_finish failed!\n");     }     close(fd);     sprintf(p,"%s.dwarf",filepath);     if(asd.global || asd.sub_link)         save_to_file(p,&asd);     //read_from_file(p,&asd);     //print(asd);     //print_pos(p);     printf("end \n");     return 0; }

点击(此处)折叠或打开

#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <errno.h> #include <string.h> #include "dwarf.h" #include "libdwarf.h" #define printf(line, ...) ; //禁用所有的printf static const char *const dwarf_regnames_i386[] = {   "eax", "ecx", "edx", "ebx",   "esp", "ebp", "esi", "edi",   "eip", "eflags", NULL,   "st0", "st1", "st2", "st3",   "st4", "st5", "st6", "st7",   NULL, NULL,   "xmm0", "xmm1", "xmm2", "xmm3",   "xmm4", "xmm5", "xmm6", "xmm7",   "mm0", "mm1", "mm2", "mm3",   "mm4", "mm5", "mm6", "mm7",   "fcw", "fsw", "mxcsr",   "es", "cs", "ss", "ds", "fs", "gs", NULL, NULL,   "tr", "ldtr" };//寄存器顺序+名字,从GDB源代码里copy过来的。。。 static const char *const dwarf_base_type[]= {     "void",     "unsigned int", "unsigned char"    ,"short unsigned int",     "long unsigned int", "signed char", "short int",     "int", "long long int", "long long unsigned int",     "long int", "char", "union", "struct" }; // 11个C基本类型 + 联合体 + 结构体 + void 没了 C就这么多了 #pragma pack(1) struct sub {     char name[8]; //函数名称     unsigned short level;//函数位于dwarf信息的第几层     unsigned char type;//返回值类型,对应dwarf_base_type结构     unsigned int low_pc;//函数的起始地址     unsigned int high_pc;//函数的结束地址     struct loc *loc;//函数执行期间寄存器偏移信息     struct var *var;//函数内的变量信息     struct sub *next;//指向下一个sub结构的单链表 }; struct loc {     unsigned int begin;//偏移开始地址     unsigned int end;//偏移结束地址     unsigned char reg;// *data -0x70 对应上面的寄存器表 其实X86 -O0编译也就4、5两个值     unsigned short base; // *(data+1)便宜值     struct loc *next;//指向下一个loc结构的单链表 }; struct var {     char name[8];//变量名字     unsigned int array; // 数组长度,0表示不是数组     unsigned char points; //这个变量是几层指针     unsigned char type; //变量类型,对应dwarf_base_type结构     unsigned int len;//变量类型长度     unsigned char loc_type; //变量地址类型     unsigned int loc;//变量地址数据,具体含义由loc_type确定     struct var *next;//指向下一个var结构的单链表 }; struct info {     struct sub * sub_link;//解析过程保存函数链表     struct var * global;//解析过程中保存全局变量链表 }; #pragma pack() struct info asd; ///// 在内存中以链表形式保存提取到的信息 unsigned int cu_low_pc;//当前正在处理的编译单元的起始地址 int is_new_cu;//进入新的编译单元 /*******************************************************************************   *函数名称:static void get_addr(Dwarf_Attribute attr, Dwarf_Addr *val)   *函数功能:提取直接地址类型属性条目中保存的地址   *输入参数:     @Dwarf_Attribute attr:地址类型属性条目   *输出参数:     @Dwarf_Addr *val:条目中包含的地址   *函数返回值:无   *其他: *******************************************************************************/ static void get_addr(Dwarf_Attribute attr, Dwarf_Addr *val) {     Dwarf_Error error = 0;     int res;     Dwarf_Addr uval = 0;     res = dwarf_formaddr(attr, &uval, &error);     if (res == DW_DLV_OK)         *val = uval; } /*******************************************************************************   *函数名称:static struct sub *new_sub(char* name,unsigned int low,unsigned int high)   *函数功能:申请一个函数信息块内存空间,并赋值   *输入参数:     @char* name:函数的名称     @unsigned int low:函数的起始地址     @unsigned int high:函数的结束地址   *输出参数:无   *函数返回值:struct sub *:申请的信息块地址   *其他: *******************************************************************************/ static struct sub *new_sub(char* name,unsigned int low,unsigned int high) {     struct sub *tmp_sub = NULL;     tmp_sub = (struct sub*) malloc(sizeof(struct sub));//申请地址     if(tmp_sub)//成功的话,填充结构体信息     {         memset(tmp_sub,0,sizeof(struct sub));         if(name)             memcpy(tmp_sub->name,name,strlen(name)>8?8:strlen(name));         tmp_sub->low_pc = low;         tmp_sub->high_pc = high;         return tmp_sub;     }     else//失败返回空         return NULL; } /*******************************************************************************   *函数名称:static void get_loc_list(Dwarf_Debug dbg, Dwarf_Die die, struct sub *sub)   *函数功能:解析一个函数类型die的下挂的寄存器偏移信息,保存到sub->loc链表中   *输入参数:     @Dwarf_Debug dbg:libdwarf库的总数据结构     @Dwarf_Die die:需要被解析的一个函数类型die     @struct sub *sub:函数DIE对应的信息块指针   *输出参数:无   *函数返回值:无   *其他:dwarf_ 开头的函数都是libdwarf库提供的函数 *******************************************************************************/ static void get_loc_list(Dwarf_Debug dbg, Dwarf_Die die, struct sub *sub) {     Dwarf_Unsigned offset=0;     Dwarf_Error error = 0;     Dwarf_Addr hipc_off;     Dwarf_Addr lopc_off;     Dwarf_Ptr data;     Dwarf_Unsigned entry_len;     Dwarf_Error err;     int res;     Dwarf_Unsigned next_entry;     Dwarf_Attribute t_attr;     struct loc *tmp=NULL,*pos;     res = dwarf_attr(die, DW_AT_frame_base, &t_attr, &error);//使用libdwarf库解析条目属性     if (res == DW_DLV_OK)     {         res = dwarf_formudata(t_attr, &offset, &error);//使用libdwarf库获取属性对应的条目链         if (res == DW_DLV_OK)             for(;;)                 {                     res = dwarf_get_loclist_entry(dbg,offset,&hipc_off,&lopc_off,&data,&entry_len,&next_entry,&err);//遍历所有条目                     if (res == DW_DLV_OK)                     {//每成功取出一个条目                         if(entry_len == 0 )                             break;                         if(entry_len > 1 )                         {                         tmp = (struct loc*) malloc(sizeof(struct loc));//申请内存                         if(tmp)                         {                             memset(tmp,0,sizeof(struct loc));                             tmp ->begin = cu_low_pc + lopc_off;                             tmp ->end = cu_low_pc + hipc_off;                             tmp ->reg = (unsigned short)*(char*)data;//保存条目信息                             if(entry_len == 2)                                 tmp ->base = (unsigned short)*(char *)(data+1);                             else                                 tmp ->base = (unsigned short)*(unsigned short *)(data+1);                             if(sub->loc)                             {                                 pos = sub->loc;//加入当前处理的函数的loc链表中                                 while(pos->next)                                     pos = pos->next;                                 pos->next = tmp;                             }                             else                                 sub->loc = tmp;                         }                         else break;                         }                         offset = next_entry;                         continue;                     }                     else break;                 }     } } /*******************************************************************************   *函数名称:static Dwarf_Die get_die(Dwarf_Debug dbg, Dwarf_Attribute attr, Dwarf_Half* tag)   *函数功能:通过偏移量取die和对应的标签   *输入参数:     @Dwarf_Debug dbg:libdwarf库的总数据结构     @Dwarf_Attribute attr:需要被操作的属性结构     @Dwarf_Half* tag:偏移值   *输出参数:无   *函数返回值:Dwarf_Die:找到的DIE的指针   *其他:dwarf_ 开头的函数都是libdwarf库提供的函数 *******************************************************************************/ static Dwarf_Die get_die(Dwarf_Debug dbg, Dwarf_Attribute attr, Dwarf_Half* tag) {//通过偏移量取die和对应的标签     Dwarf_Error error = 0;     int res;     Dwarf_Off offset;     Dwarf_Die typeDie = 0;     res = dwarf_global_formref(attr, &offset, &error);     if (res == DW_DLV_OK) {         res = dwarf_offdie(dbg, offset, &typeDie, &error);         if (res == DW_DLV_OK) {             res = dwarf_tag(typeDie, tag, &error);             if (res == DW_DLV_OK) {                 return typeDie;             }         }     }     return NULL ; } /*******************************************************************************   *函数名称:static void print_subprog(Dwarf_Debug dbg, Dwarf_Die die, struct sub **tmp_sub)   *函数功能:解析一个函数类型die的全部信息,保存到tmp_sub中   *输入参数:     @Dwarf_Debug dbg:libdwarf库的总数据结构     @Dwarf_Die die:需要被解析的一个函数类型die   *输出参数:     @struct sub **tmp_sub:返回函数信息块指针   *函数返回值:无   *其他:*******************************************************************************/ static void print_subprog(Dwarf_Debug dbg, Dwarf_Die die, struct sub **tmp_sub) {     int res;     Dwarf_Error error = 0;     Dwarf_Addr lowpc = 0;     Dwarf_Addr highpc = 0;     Dwarf_Attribute t_attr;     Dwarf_Half tag;     Dwarf_Die org_die = NULL;     char *name;     res = dwarf_attr(die, DW_AT_abstract_origin, &t_attr, &error);     if (res == DW_DLV_OK)         org_die = get_die(dbg, t_attr, &tag);     else org_die = die;     res = dwarf_diename(org_die, &name, &error);//获取函数的名称     if (res != DW_DLV_OK) {         name = NULL;     }     res = dwarf_attr(die, DW_AT_low_pc, &t_attr, &error);     if (res == DW_DLV_OK) // 获取函数的开始地址         get_addr(t_attr, &lowpc);     res = dwarf_attr(die, DW_AT_high_pc, &t_attr, &error);     if (res == DW_DLV_OK) // 获取函数的结束地址         get_addr(t_attr, &highpc);     *tmp_sub = new_sub(name,(unsigned int)lowpc,(unsigned int)highpc);//申请新的sub结构     //目前只考虑32位的,unsigned int就行     //} } /*******************************************************************************   *函数名称:static int get_array_length(Dwarf_Debug dbg, Dwarf_Die die, int *length)   *函数功能:计算一个数组属性的DIE对应的数组的具体长度   *输入参数:     @Dwarf_Debug dbg:libdwarf库的总数据结构     @Dwarf_Die die:需要被计算的die   *输出参数:     @int *length:返回长度值   *函数返回值:无   *其他: *******************************************************************************/ static int get_array_length(Dwarf_Debug dbg, Dwarf_Die die, int *length) {//数组类型的长度。。     int res;     Dwarf_Error error;     Dwarf_Die child;     Dwarf_Attribute tmp;     res = dwarf_child(die, &child, &error);     *length = 1;     Dwarf_Unsigned utmp;     if (res == DW_DLV_OK) {         while (1) {             res = dwarf_attr(child, DW_AT_upper_bound, &tmp, &error);             if (res == DW_DLV_OK) {                 res = dwarf_formudata(tmp, &utmp, &error);                 if (res != DW_DLV_OK)                     return DW_DLV_ERROR;                 else                     *length *= (utmp + 1);             }             res = dwarf_siblingof(dbg, child, &child, &error);             if (res == DW_DLV_ERROR)                 return DW_DLV_ERROR;             if (res == DW_DLV_NO_ENTRY)                 return DW_DLV_OK;         }     }     return DW_DLV_ERROR; } /*******************************************************************************   *函数名称:static void get_type(Dwarf_Debug dbg, Dwarf_Attribute attr, unsigned int *arr, unsigned short *points, unsigned short *type, unsigned int *type_len)   *函数功能:解析一个变量类型描述类型die的全部信息   *输入参数:     @Dwarf_Debug dbg:libdwarf库的总数据结构     @DDwarf_Attribute attr:需要被解析的一个变量类型die   *输出参数:     @unsigned int *arr:是否是数组类型,以及数组长度     @unsigned short *points:是否时指针类型,以及指针深度,和arr同时非0,表明是一个指针数组,目前不考虑这种情况     @unsigned short *type:具体类型值,定义对应最上面dwarf_base_type数组     @unsigned int *type_len:类型长度   *函数返回值:无   *其他:具体参见DWARF Debugging Information Format.pdf文档中“类型条目”书签标记的位置        简单来说,attr是个类型描述的开头,他指向一个属性链条,每个点上保存一个属性,便利这个链条确定最终的类型 *******************************************************************************/ static void get_type(Dwarf_Debug dbg, Dwarf_Attribute attr, unsigned int *arr, unsigned short *points, unsigned short *type, unsigned int *type_len) {     char *name = 0;     Dwarf_Half tag;     Dwarf_Unsigned size;     Dwarf_Error error = 0;     Dwarf_Attribute t_attr;     int res;     int length;     Dwarf_Die typeDie = get_die(dbg, attr, &tag);     if (typeDie) {         switch (tag) {//只处理了和标准C相关的类型         case DW_TAG_subroutine_type://函数指针,对比没意义,就不管了             *type = 255;             break;         case DW_TAG_typedef://对应C语言中typedef关键字             goto next_type;         case DW_TAG_const_type://对应C语言中const关键字             goto next_type;         case DW_TAG_pointer_type://对应C语言中变量定义中的 * 指针符             *points += 1;             goto next_type;         case DW_TAG_volatile_type://对应C语言中volatile关键字             next_type: res = dwarf_attr(typeDie, DW_AT_type, &t_attr, &error);             if (res == DW_DLV_OK) {                 get_type(dbg, t_attr, arr, points, type, type_len);             } else                 *type = 1;             break;         case DW_TAG_base_type://对应dwarf_base_type定义的C基本变量类型             res = dwarf_diename(typeDie, &name, &error);             if (res == DW_DLV_OK) {                 for(res = 0;res<sizeof(dwarf_base_type)/sizeof(char *);res++)                     if(!strncmp(name,dwarf_base_type[res],strlen(dwarf_base_type[res])))                     {                         *type = res+1;                         break;                     }                 res = dwarf_bytesize(typeDie, &size, &error);                 if (res == DW_DLV_OK) {                     *type_len = ((unsigned int)size);                 } else                     *type_len = 0;             } else                 *type = 0;             break;         case DW_TAG_array_type://对应C语言中的数组定义             res = get_array_length(dbg, typeDie, &length);             if (res == DW_DLV_OK)                 *arr = length;             goto next_type;         case DW_TAG_union_type://对应C语言中联合体定义             *type = sizeof(dwarf_base_type)/sizeof(char *) -1;             goto get_size;         case DW_TAG_structure_type://对应C语言中结构体定义             *type = sizeof(dwarf_base_type)/sizeof(char *);             get_size: res = dwarf_bytesize(typeDie, &size, &error);             if (res == DW_DLV_OK)                 *type_len = (unsigned int)size;             else                 *type_len = 0;             break;         default://非C语言类型             *type = 0;             break;         }     } } /*******************************************************************************   *函数名称:static void get_location(Dwarf_Debug dbg, Dwarf_Attribute attr, unsigned int *loc_type, unsigned int *loc)   *函数功能:解析一个地址类型die的全部信息   *输入参数:     @Dwarf_Debug dbg:libdwarf库的总数据结构     @Dwarf_Attribute attr:需要被解析的一个地址类型die   *输出参数:     @unsigned int *loc_type:返回die标签包含的地址的地址类型     @unsigned int *loc:返回die标签包含的地址的具体地址数值   *函数返回值:无   *其他:地址类型和地址数值包含[直接地址:32位线性地址][寄存器基址寻址:偏移值]等多个可能的赋值含义组合      具体参见DWARF Debugging Information Format.pdf文档中“位置描述”书签标记的位置 *******************************************************************************/ static void get_location(Dwarf_Debug dbg, Dwarf_Attribute attr, unsigned int *loc_type, unsigned int *loc) {     Dwarf_Error error = 0;     int res;     Dwarf_Locdesc *llbuf;     Dwarf_Signed lcnt;     res = dwarf_loclist(attr, &llbuf, &lcnt, &error);     if (res == DW_DLV_OK) {         *loc_type = (unsigned int) llbuf->ld_s->lr_atom;         *loc = (unsigned int)llbuf->ld_s->lr_number;         dwarf_dealloc(dbg, llbuf->ld_s, DW_DLA_LOC_BLOCK);         dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC);     } } /*******************************************************************************   *函数名称:static void print_variable(Dwarf_Debug dbg, Dwarf_Die die, struct var ** tmp_loc)   *函数功能:解析一个变量类型die的全部信息,保存到tmp_loc中   *输入参数:     @Dwarf_Debug dbg:libdwarf库的总数据结构     @Dwarf_Die die:需要被解析的一个变量类型die   *输出参数:     @struct var ** tmp_loc:返回变量信息块指针   *函数返回值:无   *其他:*******************************************************************************/ static void print_variable(Dwarf_Debug dbg, Dwarf_Die die, struct var ** tmp_loc) {     int res;     Dwarf_Error error = 0;     Dwarf_Attribute t_attr;     unsigned int arr, type_len, loc_type, loc;     unsigned short points, type ;     struct var * tmp =NULL ;     Dwarf_Die org_die = NULL;     Dwarf_Half tag;     char *name;     *tmp_loc = tmp;     res = dwarf_attr(die, DW_AT_abstract_origin, &t_attr, &error);     if (res == DW_DLV_OK)         org_die = get_die(dbg, t_attr, &tag);     else org_die = die;     res = dwarf_diename(org_die, &name, &error);     if (res != DW_DLV_OK) {         name = NULL;     }     res = dwarf_attr(die, DW_AT_declaration, &t_attr, &error);     if (res != DW_DLV_OK) { //若res == DW_DLV_OK,则是extern变量,没有位置信息,就不再保存         loc_type = loc =0;         arr = type_len = 0;         points = type = 0;         res = dwarf_attr(die, DW_AT_location, &t_attr, &error);         if (res == DW_DLV_OK) //获取变量的位置信息             get_location(dbg, t_attr, &loc_type, &loc);         if(loc_type == 0)         {             printf("no loc info !!\n");             return;         }         res = dwarf_attr(org_die, DW_AT_type, &t_attr, &error);         if (res == DW_DLV_OK) // 确定变量的类型以及长度             get_type(dbg, t_attr, &arr, &points, &type, &type_len);         if(type == 0)         {             printf("error in get_type \n ");             return;         }         if(type == 255)         {             printf("DW_TAG_subroutine_type !! \n");             return;         }         tmp = (struct var*) malloc(sizeof(struct var));//申请新的var结构体存放变量信息         if (tmp)         {             memset(tmp,0,sizeof(struct var));             if(name)                 memcpy(tmp->name,name,strlen(name)>8?8:strlen(name));             tmp->array = arr;             tmp->points = points;             tmp->type = type;             tmp->len = type_len;             tmp->loc_type = loc_type;             tmp->loc = loc;             *tmp_loc = tmp;         }     } } /*******************************************************************************   *函数名称:static void get_die_and_siblings(Dwarf_Debug dbg, Dwarf_Die in_die,int in_level)   *函数功能:递归遍历整个DWARF调试信息树,取出其中的变量、寄存器偏移和变量信息   *输入参数:     @Dwarf_Debug dbg:libdwarf库的总数据结构     @Dwarf_Die in_die:需要被遍历的头一个die     @int in_level:便利处于第几层   *输出参数:无   *函数返回值:无   *其他:*******************************************************************************/ static void get_die_and_siblings(Dwarf_Debug dbg, Dwarf_Die in_die,         int in_level) {     int res = DW_DLV_ERROR;     Dwarf_Die cur_die = in_die;     Dwarf_Die child = 0;     Dwarf_Error error;     Dwarf_Half tag;     Dwarf_Attribute t_attr;     Dwarf_Unsigned inline_tag;     Dwarf_Die sib_die = 0;     struct var *t_var , *p_var;     struct sub *t_sub , *p_sub;     struct todo     {         Dwarf_Die d;         Dwarf_Half tag;         struct todo *n;     }*todo_list,*t_todo,*p_todo;     todo_list = NULL;     for(;;)     {         res = dwarf_tag(cur_die, &tag, &error); // 取标签         if (res != DW_DLV_OK) {             printf("Error in dwarf_tag , level %d \n", in_level);             exit(1);         }         if(in_level == 1) //由于标准C不允许函数嵌套定义,SO ,1层只有全局变量和函数顶层         {             if(tag == DW_TAG_variable) //全局变量             {                 print_variable(dbg, cur_die, &t_var);                 if(asd.global) //放进全局链结尾去                 {                     p_var = asd.global;                     while(p_var->next)                         p_var = p_var->next;                     p_var->next = t_var;                 }                 else                     asd.global = t_var;             }             if(tag == DW_TAG_subprogram) //函数,判断是否时inline 然后加进SUB链 然后进child取局部变量和包含的块和inlined             {                 res = dwarf_attr(cur_die, DW_AT_inline, &t_attr, &error);                 if(res == DW_DLV_OK)                 {                     res = dwarf_formudata(t_attr, &inline_tag, &error);                     if(res != DW_DLV_OK)                         exit(1);                     if(inline_tag == DW_INL_inlined || inline_tag == DW_INL_declared_inlined)                         goto next_sib;//是inline函数 就出去继续循环 后面把非inline函数加进SUB                 }                 print_subprog(dbg, cur_die, &t_sub);                 if(t_sub)                 {                     if(is_new_cu)                     {                         is_new_cu = 0;                         cu_low_pc = t_sub->low_pc;                     }                     t_sub->level = in_level;                     t_sub->type = DW_TAG_subprogram;                     get_loc_list(dbg, cur_die, t_sub); //把loc信息添加进去                     if(asd.sub_link) //放进sub链结尾去                     {                         p_sub = asd.sub_link;                         while(p_sub->next)                             p_sub = p_sub->next;                         p_sub->next = t_sub;                     }                     else                         asd.sub_link = t_sub;                     res = dwarf_child(cur_die, &child, &error);                     if (res == DW_DLV_ERROR)                     {                         printf("Error in dwarf_child , level %d \n", in_level);                         exit(1);                     }                     if (res == DW_DLV_OK)                         get_die_and_siblings(dbg, child, in_level + 1); //进入child 也就是>1的层                 }             }         }         else if(in_level > 1) //大于1层的地方只有局部变量和块、inlined         {             if (tag == DW_TAG_formal_parameter || tag == DW_TAG_variable) //局部变量,挂到sub链最后一个的VAR指针上             {                 print_variable(dbg, cur_die, &t_var);                 p_sub = asd.sub_link;                 while(p_sub->next)                     p_sub = p_sub->next;                 if(p_sub->var)                 {                     p_var = p_sub->var;                     while(p_var->next)                         p_var = p_var->next;                     p_var->next = t_var;                 }                 else                     p_sub->var = t_var;             }             if(tag == DW_TAG_lexical_block || tag == DW_TAG_inlined_subroutine) // 先放到todo_list里面在for外面单独处理             {                 t_todo = (struct todo *) malloc(sizeof(struct todo));                 if(t_todo)                 {                     memset(t_todo,0,sizeof(struct todo));                     t_todo->d = cur_die;                     t_todo->tag = tag;                     if(todo_list)                     {                         p_todo = todo_list;                         while(p_todo->n)                             p_todo = p_todo->n;                         p_todo->n = t_todo;                     }                     else                         todo_list = t_todo;                 }             }         }         else         {//0层是变编译头信息,没啥用就直接进child             res = dwarf_child(cur_die, &child, &error);             if (res == DW_DLV_ERROR)             {                 printf("Error in dwarf_child , level %d \n", in_level);                 exit(1);             }             if (res == DW_DLV_OK)             {                 is_new_cu = 1;                 get_die_and_siblings(dbg, child, in_level + 1);             }         }         next_sib:         sib_die = 0;         res = dwarf_siblingof(dbg, cur_die, &sib_die, &error);         if (res == DW_DLV_ERROR) {             printf("Error in dwarf_siblingof , level %d \n", in_level);             exit(1);         }         if (res == DW_DLV_NO_ENTRY)             break;         if (cur_die != in_die && in_level < 2)             dwarf_dealloc(dbg, cur_die, DW_DLA_DIE);         cur_die = sib_die;     }     if(todo_list)     {         t_todo = p_todo = todo_list;         todo_list = NULL;         while(p_todo)         {             print_subprog(dbg, p_todo->d, &t_sub);             if(t_sub)             {                 t_sub->level = in_level;                 t_sub->type = p_todo->tag;                 if(asd.sub_link) //放进sub链结尾去                 {                     p_sub = asd.sub_link;                     while(p_sub->next)                         p_sub = p_sub->next;                     p_sub->next = t_sub;                 }                 else                     exit(1); //若在这里asd.sub_link依然为空,那么肯定是有错误了,因为只有在>1的时候才能进到这里                 res = dwarf_child(cur_die, &child, &error);                 if (res == DW_DLV_ERROR)                 {                     printf("Error in dwarf_child , level %d \n", in_level);                     exit(1);                 }                 if (res == DW_DLV_OK)                     get_die_and_siblings(dbg, child, in_level + 1); //进入child             }             p_todo = p_todo->n;             dwarf_dealloc(dbg, t_todo->d , DW_DLA_DIE);             free(t_todo);             t_todo = p_todo;         }     } } /*******************************************************************************   *函数名称:static void read_cu_list(Dwarf_Debug dbg)   *函数功能:遍历调试信息中包含的全部CU头,提取其中的信息   *输入参数:     @Dwarf_Debug dbg:libdwarf库的总数据结构   *输出参数:无   *函数返回值:无   *其他:*******************************************************************************/ static void read_cu_list(Dwarf_Debug dbg) {//一次取出一个CU头     Dwarf_Unsigned cu_header_length = 0;     Dwarf_Half version_stamp = 0;     Dwarf_Unsigned abbrev_offset = 0;     Dwarf_Half address_size = 0;     Dwarf_Unsigned next_cu_header = 0;     Dwarf_Error error;     for (;;) {         Dwarf_Die no_die = 0;         Dwarf_Die cu_die = 0;         int res = DW_DLV_ERROR;         res = dwarf_next_cu_header(dbg, &cu_header_length, &version_stamp,                 &abbrev_offset, &address_size, &next_cu_header, &error);//取出一个CU         if (res == DW_DLV_ERROR) {             printf("Error in dwarf_next_cu_header\n");             exit(1);         }         if (res == DW_DLV_NO_ENTRY) {             /* Done. */             return;         }         /* The CU will have a single sibling, a cu_die. */         res = dwarf_siblingof(dbg, no_die, &cu_die, &error);         if (res == DW_DLV_ERROR) {             printf("Error in dwarf_siblingof on CU die \n");             exit(1);         }         if (res == DW_DLV_NO_ENTRY) {             /* Impossible case. */             printf("no entry! in dwarf_siblingof on CU die \n");             exit(1);         }         get_die_and_siblings(dbg, cu_die, 0);//拿到CU后,进入第0层,开始递归遍历         dwarf_dealloc(dbg, cu_die, DW_DLA_DIE);     } } /*******************************************************************************   *函数名称:static void save_to_file(char *path, struct info *asd)   *函数功能:将全局链表中存放的调试信息保存到文件中   *输入参数:     @char *path:保存文件的路径     @struct info *asd:要保存的信息所在的链表   *输出参数:无   *函数返回值:无   *其他:*******************************************************************************/ static void save_to_file(char *path, struct info *asd) {     FILE * f ,* fpos;     char buf[255];     static const int size[] =     {             sizeof(struct sub) - 3 * sizeof(void *),             sizeof(struct loc) - sizeof(void *),             sizeof(struct var) - sizeof(void *)     };     static const unsigned char tag[] =     {             0x00,0x01,0x02,0x03     };     struct sub *p_sub_1, *p_sub_2;     struct loc *p_loc_1, *p_loc_2;     struct var *p_var_1, *p_var_2;     unsigned int pos;     pos = 0;     sprintf(buf,"%s.pos",path);//索引文件文件名     f = fopen(path,"w");//打开调试信息文件     fpos = fopen(buf,"w");//打开索引文件     if(f)     {         p_var_1 = asd->global;         while(p_var_1)         {//首先保存全局变量信息到调试信息文件             fwrite(tag+3, 1, 1, f);             fwrite(p_var_1, size[2], 1, f);             fwrite(tag, 1, 1, f);             p_var_2 = p_var_1;             p_var_1 = p_var_1->next;             free(p_var_2);             pos += size[2] + 2;         }         fwrite(&pos,4,1,fpos);//记录全局变量信息长度到索引文件         asd->global = NULL;         p_sub_1 = asd->sub_link;         while(p_sub_1)         {//保存变量信息             fwrite(tag+1, 1, 1, f);             fwrite(p_sub_1, size[0], 1, f);             fwrite(tag, 1, 1, f);             fwrite(&p_sub_1->low_pc, sizeof(long), 1, fpos);//函数的开始地址写入索引文件             fwrite(&p_sub_1->high_pc, sizeof(long), 1, fpos);//函数的解释地址写入索引文件             fwrite(&pos,4,1,fpos);//函数在调试信息文件中的位置,写入索引文件             pos += size[0] + 2;             p_loc_1 = p_sub_1->loc;             while(p_loc_1)             {//变量执行期间寄存偏移情况                 fwrite(tag+2, 1, 1, f);                 fwrite(p_loc_1, size[1], 1, f);                 fwrite(tag, 1, 1, f);                 p_loc_2 = p_loc_1;                 p_loc_1 = p_loc_1->next;                 free(p_loc_2);                 pos += size[1] + 2;             }             p_var_1 = p_sub_1->var;             while(p_var_1)             {//函数的局部变量                 fwrite(tag+3, 1, 1, f);                 fwrite(p_var_1, size[2], 1, f);                 fwrite(tag, 1, 1, f);                 p_var_2 = p_var_1;                 p_var_1 = p_var_1->next;                 free(p_var_2);                 pos += size[2] + 2;             }             p_sub_2 = p_sub_1;             p_sub_1 = p_sub_1->next;             free(p_sub_2);         }         asd->sub_link = NULL;         fclose(f);//关闭,完成         fclose(fpos);     } } /*//一些测试函数 static void read_from_file(char *path, struct info *asd) {//读取出来看文件是否正确     FILE * f;     static const int size[] =     {             sizeof(struct sub) - 3 * sizeof(void *),             sizeof(struct loc) - sizeof(void *),             sizeof(struct var) - sizeof(void *)     };     struct sub *p_sub_1, *p_sub_2;     struct loc *p_loc_1, *p_loc_2;     struct var *p_var_1, *p_var_2;     char t;     int is_global = 1;     f = fopen(path,"r");     if(f)     {         while(!feof(f))         {             fread(&t, 1, 1, f);             switch(t)             {             case 3:                 p_var_2 = (struct var *) malloc(sizeof(struct var));                 if(p_var_2)                 {                     memset(p_var_2, 0, sizeof(struct var));                     fread(p_var_2, size[2], 1, f);                     if(is_global)                     {                         if(asd->global)                         {                             p_var_1 = asd->global;                             while(p_var_1 ->next)                                 p_var_1 = p_var_1->next;                             p_var_1->next = p_var_2;                         }                         else                             asd->global = p_var_2;                     }                     else                     {                         p_sub_1 = asd->sub_link;                         while(p_sub_1->next)                             p_sub_1 = p_sub_1->next;                         if(p_sub_1->var)                         {                             p_var_1 = p_sub_1->var;                             while(p_var_1 ->next)                                 p_var_1 = p_var_1->next;                             p_var_1->next = p_var_2;                         }                         else                             p_sub_1->var = p_var_2;                     }                 }                 break;             case 1:                 p_sub_2 = (struct sub *) malloc(sizeof(struct sub));                 if(p_sub_2)                 {                     is_global = 0;                     memset(p_sub_2, 0, sizeof(struct sub));                     fread(p_sub_2, size[0], 1, f);                     if(asd->sub_link)                     {                         p_sub_1 = asd->sub_link;                         while(p_sub_1->next)                             p_sub_1 = p_sub_1->next;                         p_sub_1->next = p_sub_2;                     }                     else                         asd->sub_link = p_sub_2;                 }                 break;             case 2:                 p_loc_2 = (struct loc *) malloc(sizeof(struct loc));                 if(p_loc_2)                 {                     memset(p_loc_2, 0, sizeof(struct loc));                     fread(p_loc_2, size[1], 1, f);                     if(!asd->sub_link)                         exit(1);                     p_sub_1 = asd->sub_link;                     while(p_sub_1->next)                         p_sub_1 = p_sub_1->next;                     if(p_sub_1->loc)                     {                         p_loc_1 = p_sub_1->loc;                         while(p_loc_1 ->next)                             p_loc_1 = p_loc_1->next;                         p_loc_1->next = p_loc_2;                     }                     else                         p_sub_1->loc = p_loc_2;                 }                 break;             }             fread(&t, 1, 1, f);             if(t)                 exit(1);         }     } } static void print_pos(char *path) {//打印索引     FILE * f ,* fp;     char buf[255], *b,name[9];     unsigned int *bp;     int s,sp,pos;     sprintf(buf,"%s.pos",path);     f = fopen(path,"r");     fp = fopen(buf,"r");     fseek(f,0,2);     fseek(fp,0,2);     s = ftell(f);     sp = ftell(fp);     b = (char *) malloc(s);     bp = (unsigned int *) malloc(sp);     fseek(f,0,0);     fseek(fp,0,0);     fread(b,s,1,f);     fread(bp,s,1,fp);     fclose(f);     fclose(fp);     printf("全局比啊两数据长度:%d\n",*bp);     pos = 1;     while(pos < sp/4)     {         printf("low: x\n",*(bp+pos));         printf("hig: x\n",*(bp+pos+1));         memset(name,0,9);         memcpy(name,b+*(bp+pos+2)+1,8);         printf("name:%s\n",name);         pos+=3;     } } static void print(struct info asd) {//打印全部保存的调试信息     struct sub *p_sub_1;     struct loc *p_loc_1;     struct var *p_var_1;     char n[9];     p_var_1 = asd.global;     while(p_var_1)     {         memset(n,0,9);         memcpy(n,p_var_1->name,8);         printf("< 1 > 变量名: %s\n< 1 > ",n);         if ( DW_OP_addr == p_var_1->loc_type)             printf("直接地址: %x \n",(int) p_var_1->loc);         else if(p_var_1->loc_type >= DW_OP_breg0 && p_var_1->loc_type <= DW_OP_breg31)             printf("基址寻址: %d (%s)\n", ((int)p_var_1->loc), *(dwarf_regnames_i386+p_var_1->loc_type-DW_OP_breg0));         else if(p_var_1->loc_type >= DW_OP_reg0 && p_var_1->loc_type <= DW_OP_reg31)             printf("通用寄存器: reg%d \n",p_var_1->loc - DW_OP_reg0);         else if(p_var_1->loc_type == DW_OP_fbreg)             printf("loclist: %d \n",((int)p_var_1->loc));         else             printf("Unknow location \n");//不是C的不管丫的         printf("< %d > 数组: %d\n",1,p_var_1->array);         printf("< %d > 指针: %d\n",1,p_var_1->points);         printf("< %d > 类型: %s\n",1,dwarf_base_type[p_var_1->type - 1]);         printf("< 1 > 大小: %d\n\n",p_var_1->len);         p_var_1 = p_var_1->next;     }     p_sub_1 = asd.sub_link;     while(p_sub_1)     {         p_loc_1 = p_sub_1->loc;         p_var_1 = p_sub_1->var;         memset(n,0,9);         memcpy(n,p_sub_1->name,8);         printf("< %d >函数名: %s\n",p_sub_1->level,p_sub_1->type == DW_TAG_subprogram?n:"局部块");         printf("< %d >low_pc : 0xx \n",p_sub_1->level,p_sub_1->low_pc);         printf("< %d >high_pc : 0xx \n\n",p_sub_1->level,p_sub_1->high_pc);         while(p_loc_1)         {             printf("< %d > loclist: 0xx -- 0xx : (%s) %d \n",p_sub_1->level,p_loc_1->begin,p_loc_1->end,*(dwarf_regnames_i386+(p_loc_1->reg>0x70?p_loc_1->reg-0x70:10)),p_loc_1->base);             p_loc_1 = p_loc_1->next;         }         while(p_var_1)         {             memset(n,0,9);             memcpy(n,p_var_1->name,8);             printf("\n< %d > 变量名: %s\n< %d > ",p_sub_1->level+1,n,p_sub_1->level+1);             if ( DW_OP_addr == p_var_1->loc_type)                 printf("直接地址: %x \n",(int) p_var_1->loc);             else if(p_var_1->loc_type >= DW_OP_breg0 && p_var_1->loc_type <= DW_OP_breg31)                 printf("基址寻址: %d (%s)\n", ((int)p_var_1->loc), *(dwarf_regnames_i386+p_var_1->loc_type-DW_OP_breg0));             else if(p_var_1->loc_type >= DW_OP_reg0 && p_var_1->loc_type <= DW_OP_reg31)                 printf("通用寄存器: reg%d \n",p_var_1->loc - DW_OP_reg0);             else if(p_var_1->loc_type == DW_OP_fbreg)                 printf("loclist: %d \n",((int)p_var_1->loc));             else                 printf("Unknow location \n");//不是C的不管丫的             printf("< %d > 数组: %d\n",p_sub_1->level+1,p_var_1->array);             printf("< %d > 指针: %d\n",p_sub_1->level+1,p_var_1->points);             printf("< %d > 类型: %s\n",p_sub_1->level+1,dwarf_base_type[p_var_1->type - 1]);             printf("< %d > 大小: %d\n\n",p_sub_1->level+1,p_var_1->len);             p_var_1 = p_var_1->next;         }         p_sub_1 = p_sub_1->next;     } } */ int main(int argc, char **argv) {//初始化dbg     Dwarf_Debug dbg = 0;     int fd = -1;     const char *filepath = "<stdin>";     char p[255];     int res = DW_DLV_ERROR;     Dwarf_Error error;     Dwarf_Handler errhand = 0;     Dwarf_Ptr errarg = 0;     if (argc < 2)         fd = 0;     else     {         filepath = argv[1];         fd = open(filepath, O_RDONLY);     }     if (fd <= 0)     {         printf("Failure attempting to open \"%s\"\n", filepath);         exit(1);     }     res = dwarf_init(fd, DW_DLC_READ, errhand, errarg, &dbg, &error);     if (res != DW_DLV_OK) {         printf("Giving up, cannot do DWARF processing\n");         exit(1);     }     read_cu_list(dbg);//解析工作     res = dwarf_finish(dbg, &error);     if (res != DW_DLV_OK) {         printf("dwarf_finish failed!\n");     }     close(fd);     sprintf(p,"%s.dwarf",filepath);     if(asd.global || asd.sub_link)         save_to_file(p,&asd);     //read_from_file(p,&asd);     //print(asd);     //print_pos(p);     printf("end \n");     return 0; } <script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script> 阅读(316) | 评论(0) | 转发(0) | 1

上一篇:笔试题(2)

下一篇:链表

相关热门文章 linux 常见服务端口xmanager 2.0 for linux配置【ROOTFS搭建】busybox的httpd...openwrt中luci学习笔记Linux里如何查找文件内容... 给主人留下些什么吧!~~ 评论热议
转载请注明原文地址: https://www.6miu.com/read-55747.html

最新回复(0)