Chinaunix首页 | 论坛 | 博客
  • 博客访问: 522486
  • 博文数量: 184
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1172
  • 用 户 组: 普通用户
  • 注册时间: 2016-06-21 13:40
个人简介

技术改变命运

文章分类

全部博文(184)

文章存档

2020年(16)

2017年(12)

2016年(156)

我的朋友

分类: LINUX

2016-08-06 19:30:27

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

点击(此处)折叠或打开

  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <fcntl.h>
  4. #include <stdlib.h>
  5. #include <unistd.h>
  6. #include <stdio.h>
  7. #include <errno.h>
  8. #include <string.h>
  9. #include "dwarf.h"
  10. #include "libdwarf.h"

  11. #define printf(line, ...) ; //禁用所有的printf

  12. static const char *const dwarf_regnames_i386[] =
  13. {
  14.   "eax", "ecx", "edx", "ebx",
  15.   "esp", "ebp", "esi", "edi",
  16.   "eip", "eflags", NULL,
  17.   "st0", "st1", "st2", "st3",
  18.   "st4", "st5", "st6", "st7",
  19.   NULL, NULL,
  20.   "xmm0", "xmm1", "xmm2", "xmm3",
  21.   "xmm4", "xmm5", "xmm6", "xmm7",
  22.   "mm0", "mm1", "mm2", "mm3",
  23.   "mm4", "mm5", "mm6", "mm7",
  24.   "fcw", "fsw", "mxcsr",
  25.   "es", "cs", "ss", "ds", "fs", "gs", NULL, NULL,
  26.   "tr", "ldtr"
  27. };//寄存器顺序+名字,从GDB源代码里copy过来的。。。

  28. static const char *const dwarf_base_type[]=
  29. {
  30.     "void",
  31.     "unsigned int", "unsigned char"    ,"short unsigned int",
  32.     "long unsigned int", "signed char", "short int",
  33.     "int", "long long int", "long long unsigned int",
  34.     "long int", "char", "union", "struct"
  35. }; // 11个C基本类型 + 联合体 + 结构体 + void 没了 C就这么多了
  36. #pragma pack(1)
  37. struct sub
  38. {
  39.     char name[8]; //函数名称
  40.     unsigned short level;//函数位于dwarf信息的第几层
  41.     unsigned char type;//返回值类型,对应dwarf_base_type结构
  42.     unsigned int low_pc;//函数的起始地址
  43.     unsigned int high_pc;//函数的结束地址
  44.     struct loc *loc;//函数执行期间寄存器偏移信息
  45.     struct var *var;//函数内的变量信息
  46.     struct sub *next;//指向下一个sub结构的单链表
  47. };

  48. struct loc
  49. {
  50.     unsigned int begin;//偏移开始地址
  51.     unsigned int end;//偏移结束地址
  52.     unsigned char reg;// *data -0x70 对应上面的寄存器表 其实X86 -O0编译也就4、5两个值
  53.     unsigned short base; // *(data+1)便宜值
  54.     struct loc *next;//指向下一个loc结构的单链表
  55. };

  56. struct var
  57. {
  58.     char name[8];//变量名字
  59.     unsigned int array; // 数组长度,0表示不是数组
  60.     unsigned char points; //这个变量是几层指针
  61.     unsigned char type; //变量类型,对应dwarf_base_type结构
  62.     unsigned int len;//变量类型长度
  63.     unsigned char loc_type; //变量地址类型
  64.     unsigned int loc;//变量地址数据,具体含义由loc_type确定
  65.     struct var *next;//指向下一个var结构的单链表
  66. };

  67. struct info
  68. {
  69.     struct sub * sub_link;//解析过程保存函数链表
  70.     struct var * global;//解析过程中保存全局变量链表
  71. };
  72. #pragma pack()

  73. struct info asd; ///// 在内存中以链表形式保存提取到的信息

  74. unsigned int cu_low_pc;//当前正在处理的编译单元的起始地址
  75. int is_new_cu;//进入新的编译单元
  76. /*******************************************************************************
  77.   *函数名称:static void get_addr(Dwarf_Attribute attr, Dwarf_Addr *val)
  78.   *函数功能:提取直接地址类型属性条目中保存的地址
  79.   *输入参数:
  80.     @Dwarf_Attribute attr:地址类型属性条目
  81.   *输出参数:
  82.     @Dwarf_Addr *val:条目中包含的地址
  83.   *函数返回值:
  84.   *其他:
  85. *******************************************************************************/
  86. static void get_addr(Dwarf_Attribute attr, Dwarf_Addr *val) {
  87.     Dwarf_Error error = 0;
  88.     int res;
  89.     Dwarf_Addr uval = 0;
  90.     res = dwarf_formaddr(attr, &uval, &error);
  91.     if (res == DW_DLV_OK)
  92.         *val = uval;
  93. }
  94. /*******************************************************************************
  95.   *函数名称:static struct sub *new_sub(char* name,unsigned int low,unsigned int high)
  96.   *函数功能:申请一个函数信息块内存空间,并赋值
  97.   *输入参数:
  98.     @char* name:函数的名称
  99.     @unsigned int low:函数的起始地址
  100.     @unsigned int high:函数的结束地址
  101.   *输出参数:
  102.   *函数返回值:struct sub *:申请的信息块地址
  103.   *其他:
  104. *******************************************************************************/
  105. static struct sub *new_sub(char* name,unsigned int low,unsigned int high)
  106. {
  107.     struct sub *tmp_sub = NULL;
  108.     tmp_sub = (struct sub*) malloc(sizeof(struct sub));//申请地址
  109.     if(tmp_sub)//成功的话,填充结构体信息
  110.     {
  111.         memset(tmp_sub,0,sizeof(struct sub));
  112.         if(name)
  113.             memcpy(tmp_sub->name,name,strlen(name)>8?8:strlen(name));
  114.         tmp_sub->low_pc = low;
  115.         tmp_sub->high_pc = high;
  116.         return tmp_sub;
  117.     }
  118.     else//失败返回空
  119.         return NULL;
  120. }
  121. /*******************************************************************************
  122.   *函数名称:static void get_loc_list(Dwarf_Debug dbg, Dwarf_Die die, struct sub *sub)
  123.   *函数功能:解析一个函数类型die的下挂的寄存器偏移信息,保存到sub->loc链表中
  124.   *输入参数:
  125.     @Dwarf_Debug dbg:libdwarf库的总数据结构
  126.     @Dwarf_Die die:需要被解析的一个函数类型die
  127.     @struct sub *sub:函数DIE对应的信息块指针
  128.   *输出参数:
  129.   *函数返回值:
  130.   *其他:dwarf_ 开头的函数都是libdwarf库提供的函数
  131. *******************************************************************************/
  132. static void get_loc_list(Dwarf_Debug dbg, Dwarf_Die die, struct sub *sub)
  133. {
  134.     Dwarf_Unsigned offset=0;
  135.     Dwarf_Error error = 0;
  136.     Dwarf_Addr hipc_off;
  137.     Dwarf_Addr lopc_off;
  138.     Dwarf_Ptr data;
  139.     Dwarf_Unsigned entry_len;
  140.     Dwarf_Error err;
  141.     int res;
  142.     Dwarf_Unsigned next_entry;
  143.     Dwarf_Attribute t_attr;
  144.     struct loc *tmp=NULL,*pos;

  145.     res = dwarf_attr(die, DW_AT_frame_base, &t_attr, &error);//使用libdwarf库解析条目属性
  146.     if (res == DW_DLV_OK)
  147.     {
  148.         res = dwarf_formudata(t_attr, &offset, &error);//使用libdwarf库获取属性对应的条目链
  149.         if (res == DW_DLV_OK)
  150.             for(;;)
  151.                 {
  152.                     res = dwarf_get_loclist_entry(dbg,offset,&hipc_off,&lopc_off,&data,&entry_len,&next_entry,&err);//遍历所有条目
  153.                     if (res == DW_DLV_OK)
  154.                     {//每成功取出一个条目
  155.                         if(entry_len == 0 )
  156.                             break;
  157.                         if(entry_len > 1 )
  158.                         {
  159.                         tmp = (struct loc*) malloc(sizeof(struct loc));//申请内存
  160.                         if(tmp)
  161.                         {
  162.                             memset(tmp,0,sizeof(struct loc));
  163.                             tmp ->begin = cu_low_pc + lopc_off;
  164.                             tmp ->end = cu_low_pc + hipc_off;
  165.                             tmp ->reg = (unsigned short)*(char*)data;//保存条目信息
  166.                             if(entry_len == 2)
  167.                                 tmp ->base = (unsigned short)*(char *)(data+1);
  168.                             else
  169.                                 tmp ->base = (unsigned short)*(unsigned short *)(data+1);
  170.                             if(sub->loc)
  171.                             {
  172.                                 pos = sub->loc;//加入当前处理的函数的loc链表中
  173.                                 while(pos->next)
  174.                                     pos = pos->next;
  175.                                 pos->next = tmp;
  176.                             }
  177.                             else
  178.                                 sub->loc = tmp;
  179.                         }
  180.                         else break;
  181.                         }
  182.                         offset = next_entry;
  183.                         continue;
  184.                     }
  185.                     else break;
  186.                 }
  187.     }
  188. }
  189. /*******************************************************************************
  190.   *函数名称:static Dwarf_Die get_die(Dwarf_Debug dbg, Dwarf_Attribute attr, Dwarf_Half* tag)
  191.   *函数功能:通过偏移量取die和对应的标签
  192.   *输入参数:
  193.     @Dwarf_Debug dbg:libdwarf库的总数据结构
  194.     @Dwarf_Attribute attr:需要被操作的属性结构
  195.     @Dwarf_Half* tag:偏移值
  196.   *输出参数:
  197.   *函数返回值:Dwarf_Die:找到的DIE的指针
  198.   *其他:dwarf_ 开头的函数都是libdwarf库提供的函数
  199. *******************************************************************************/
  200. static Dwarf_Die get_die(Dwarf_Debug dbg, Dwarf_Attribute attr, Dwarf_Half* tag) {//通过偏移量取die和对应的标签
  201.     Dwarf_Error error = 0;
  202.     int res;
  203.     Dwarf_Off offset;
  204.     Dwarf_Die typeDie = 0;
  205.     res = dwarf_global_formref(attr, &offset, &error);
  206.     if (res == DW_DLV_OK) {
  207.         res = dwarf_offdie(dbg, offset, &typeDie, &error);
  208.         if (res == DW_DLV_OK) {
  209.             res = dwarf_tag(typeDie, tag, &error);
  210.             if (res == DW_DLV_OK) {
  211.                 return typeDie;
  212.             }
  213.         }
  214.     }
  215.     return NULL ;
  216. }
  217. /*******************************************************************************
  218.   *函数名称:static void print_subprog(Dwarf_Debug dbg, Dwarf_Die die, struct sub **tmp_sub)
  219.   *函数功能:解析一个函数类型die的全部信息,保存到tmp_sub中
  220.   *输入参数:
  221.     @Dwarf_Debug dbg:libdwarf库的总数据结构
  222.     @Dwarf_Die die:需要被解析的一个函数类型die
  223.   *输出参数:
  224.     @struct sub **tmp_sub:返回函数信息块指针
  225.   *函数返回值:
  226.   *其他:
  227. *******************************************************************************/
  228. static void print_subprog(Dwarf_Debug dbg, Dwarf_Die die, struct sub **tmp_sub) {
  229.     int res;
  230.     Dwarf_Error error = 0;
  231.     Dwarf_Addr lowpc = 0;
  232.     Dwarf_Addr highpc = 0;
  233.     Dwarf_Attribute t_attr;
  234.     Dwarf_Half tag;
  235.     Dwarf_Die org_die = NULL;
  236.     char *name;
  237.     res = dwarf_attr(die, DW_AT_abstract_origin, &t_attr, &error);
  238.     if (res == DW_DLV_OK)
  239.         org_die = get_die(dbg, t_attr, &tag);
  240.     else org_die = die;
  241.     res = dwarf_diename(org_die, &name, &error);//获取函数的名称
  242.     if (res != DW_DLV_OK) {
  243.         name = NULL;
  244.     }
  245.     res = dwarf_attr(die, DW_AT_low_pc, &t_attr, &error);
  246.     if (res == DW_DLV_OK) // 获取函数的开始地址
  247.         get_addr(t_attr, &lowpc);
  248.     res = dwarf_attr(die, DW_AT_high_pc, &t_attr, &error);
  249.     if (res == DW_DLV_OK) // 获取函数的结束地址
  250.         get_addr(t_attr, &highpc);
  251.     *tmp_sub = new_sub(name,(unsigned int)lowpc,(unsigned int)highpc);//申请新的sub结构
  252.     //目前只考虑32位的,unsigned int就行
  253.     //}
  254. }

  255. /*******************************************************************************
  256.   *函数名称:static int get_array_length(Dwarf_Debug dbg, Dwarf_Die die, int *length)
  257.   *函数功能:计算一个数组属性的DIE对应的数组的具体长度
  258.   *输入参数:
  259.     @Dwarf_Debug dbg:libdwarf库的总数据结构
  260.     @Dwarf_Die die:需要被计算的die
  261.   *输出参数:
  262.     @int *length:返回长度值
  263.   *函数返回值:
  264.   *其他:
  265. *******************************************************************************/
  266. static int get_array_length(Dwarf_Debug dbg, Dwarf_Die die, int *length) {//数组类型的长度。。
  267.     int res;
  268.     Dwarf_Error error;
  269.     Dwarf_Die child;
  270.     Dwarf_Attribute tmp;
  271.     res = dwarf_child(die, &child, &error);
  272.     *length = 1;
  273.     Dwarf_Unsigned utmp;
  274.     if (res == DW_DLV_OK) {
  275.         while (1) {
  276.             res = dwarf_attr(child, DW_AT_upper_bound, &tmp, &error);
  277.             if (res == DW_DLV_OK) {
  278.                 res = dwarf_formudata(tmp, &utmp, &error);
  279.                 if (res != DW_DLV_OK)
  280.                     return DW_DLV_ERROR;
  281.                 else
  282.                     *length *= (u管理文章tmp + 1);
  283.             }
  284.             res = dwarf_siblingof(dbg, child, &child, &error);
  285.             if (res == DW_DLV_ERROR)
  286.                 return DW_DLV_ERROR;
  287.             if (res == DW_DLV_NO_ENTRY)
  288.                 return DW_DLV_OK;
  289.         }
  290.     }
  291.     return DW_DLV_ERROR;
  292. }
  293. /*******************************************************************************
  294.   *函数名称:static void get_type(Dwarf_Debug dbg, Dwarf_Attribute attr, unsigned int *arr, unsigned short *points, unsigned short *type, unsigned int *type_len)
  295.   *函数功能:解析一个变量类型描述类型die的全部信息
  296.   *输入参数:
  297.     @Dwarf_Debug dbg:libdwarf库的总数据结构
  298.     @DDwarf_Attribute attr:需要被解析的一个变量类型die
  299.   *输出参数:
  300.     @unsigned int *arr:是否是数组类型,以及数组长度
  301.     @unsigned short *points:是否时指针类型,以及指针深度,和arr同时非0,表明是一个指针数组,目前不考虑这种情况
  302.     @unsigned short *type:具体类型值,定义对应最上面dwarf_base_type数组
  303.     @unsigned int *type_len:类型长度
  304.   *函数返回值:
  305.   *其他:具体参见DWARF Debugging Information Format.pdf文档中“类型条目”书签标记的位置
  306.        简单来说,attr是个类型描述的开头,他指向一个属性链条,每个点上保存一个属性,便利这个链条确定最终的类型
  307. *******************************************************************************/
  308. static void get_type(Dwarf_Debug dbg, Dwarf_Attribute attr, unsigned int *arr, unsigned short *points, unsigned short *type, unsigned int *type_len) {
  309.     char *name = 0;
  310.     Dwarf_Half tag;
  311.     Dwarf_Unsigned size;
  312.     Dwarf_Error error = 0;
  313.     Dwarf_Attribute t_attr;
  314.     int res;
  315.     int length;
  316.     Dwarf_Die typeDie = get_die(dbg, attr, &tag);
  317.     if (typeDie) {
  318.         switch (tag) {//只处理了和标准C相关的类型
  319.         case DW_TAG_subroutine_type://函数指针,对比没意义,就不管了
  320.             *type = 255;
  321.             break;
  322.         case DW_TAG_typedef://对应C语言中typedef关键字
  323.             goto next_type;
  324.         case DW_TAG_const_type://对应C语言中const关键字
  325.             goto next_type;
  326.         case DW_TAG_pointer_type://对应C语言中变量定义中的 * 指针符
  327.             *points += 1;
  328.             goto next_type;
  329.         case DW_TAG_volatile_type://对应C语言中volatile关键字
  330.             next_type: res = dwarf_attr(typeDie, DW_AT_type, &t_attr, &error);
  331.             if (res == DW_DLV_OK) {
  332.                 get_type(dbg, t_attr, arr, points, type, type_len);
  333.             } else
  334.                 *type = 1;
  335.             break;
  336.         case DW_TAG_base_type://对应dwarf_base_type定义的C基本变量类型
  337.             res = dwarf_diename(typeDie, &name, &error);
  338.             if (res == DW_DLV_OK) {
  339.                 for(res = 0;res<sizeof(dwarf_base_type)/sizeof(char *);res++)
  340.                     if(!strncmp(name,dwarf_base_type[res],strlen(dwarf_base_type[res])))
  341.                     {
  342.                         *type = res+1;
  343.                         break;
  344.                     }
  345.                 res = dwarf_bytesize(typeDie, &size, &error);
  346.                 if (res == DW_DLV_OK) {
  347.                     *type_len = ((unsigned int)size);
  348.                 } else
  349.                     *type_len = 0;
  350.             } else
  351.                 *type = 0;
  352.             break;
  353.         case DW_TAG_array_type://对应C语言中的数组定义
  354.             res = get_array_length(dbg, typeDie, &length);
  355.             if (res == DW_DLV_OK)
  356.                 *arr = length;
  357.             goto next_type;
  358.         case DW_TAG_union_type://对应C语言中联合体定义
  359.             *type = sizeof(dwarf_base_type)/sizeof(char *) -1;
  360.             goto get_size;
  361.         case DW_TAG_structure_type://对应C语言中结构体定义
  362.             *type = sizeof(dwarf_base_type)/sizeof(char *);
  363.             get_size: res = dwarf_bytesize(typeDie, &size, &error);
  364.             if (res == DW_DLV_OK)
  365.                 *type_len = (unsigned int)size;
  366.             else
  367.                 *type_len = 0;
  368.             break;
  369.         default://非C语言类型
  370.             *type = 0;
  371.             break;
  372.         }
  373.     }
  374. }
  375. /*******************************************************************************
  376.   *函数名称:static void get_location(Dwarf_Debug dbg, Dwarf_Attribute attr, unsigned int *loc_type, unsigned int *loc)
  377.   *函数功能:解析一个地址类型die的全部信息
  378.   *输入参数:
  379.     @Dwarf_Debug dbg:libdwarf库的总数据结构
  380.     @Dwarf_Attribute attr:需要被解析的一个地址类型die
  381.   *输出参数:
  382.     @unsigned int *loc_type:返回die标签包含的地址的地址类型
  383.     @unsigned int *loc:返回die标签包含的地址的具体地址数值
  384.   *函数返回值:
  385.   *其他:地址类型和地址数值包含[直接地址:32位线性地址][寄存器基址寻址:偏移值]等多个可能的赋值含义组合
  386.      具体参见DWARF Debugging Information Format.pdf文档中“位置描述”书签标记的位置
  387. *******************************************************************************/
  388. static void get_location(Dwarf_Debug dbg, Dwarf_Attribute attr, unsigned int *loc_type, unsigned int *loc) {
  389.     Dwarf_Error error = 0;
  390.     int res;
  391.     Dwarf_Locdesc *llbuf;
  392.     Dwarf_Signed lcnt;
  393.     res = dwarf_loclist(attr, &llbuf, &lcnt, &error);
  394.     if (res == DW_DLV_OK) {
  395.         *loc_type = (unsigned int) llbuf->ld_s->lr_atom;
  396.         *loc = (unsigned int)llbuf->ld_s->lr_number;
  397.         dwarf_dealloc(dbg, llbuf->ld_s, DW_DLA_LOC_BLOCK);
  398.         dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC);
  399.     }
  400. }
  401. /*******************************************************************************
  402.   *函数名称:static void print_variable(Dwarf_Debug dbg, Dwarf_Die die, struct var ** tmp_loc)
  403.   *函数功能:解析一个变量类型die的全部信息,保存到tmp_loc中
  404.   *输入参数:
  405.     @Dwarf_Debug dbg:libdwarf库的总数据结构
  406.     @Dwarf_Die die:需要被解析的一个变量类型die
  407.   *输出参数:
  408.     @struct var ** tmp_loc:返回变量信息块指针
  409.   *函数返回值:
  410.   *其他:
  411. *******************************************************************************/
  412. static void print_variable(Dwarf_Debug dbg, Dwarf_Die die, struct var ** tmp_loc) {
  413.     int res;
  414.     Dwarf_Error error = 0;
  415.     Dwarf_Attribute t_attr;
  416.     unsigned int arr, type_len, loc_type, loc;
  417.     unsigned short points, type ;
  418.     struct var * tmp =NULL ;
  419.     Dwarf_Die org_die = NULL;
  420.     Dwarf_Half tag;
  421.     char *name;

  422.     *tmp_loc = tmp;
  423.     res = dwarf_attr(die, DW_AT_abstract_origin, &t_attr, &error);
  424.     if (res == DW_DLV_OK)
  425.         org_die = get_die(dbg, t_attr, &tag);
  426.     else org_die = die;
  427.     res = dwarf_diename(org_die, &name, &error);
  428.     if (res != DW_DLV_OK) {
  429.         name = NULL;
  430.     }

  431.     res = dwarf_attr(die, DW_AT_declaration, &t_attr, &error);
  432.     if (res != DW_DLV_OK) { //若res == DW_DLV_OK,则是extern变量,没有位置信息,就不再保存
  433.         loc_type = loc =0;
  434.         arr = type_len = 0;
  435.         points = type = 0;

  436.         res = dwarf_attr(die, DW_AT_location, &t_attr, &error);
  437.         if (res == DW_DLV_OK) //获取变量的位置信息
  438.             get_location(dbg, t_attr, &loc_type, &loc);

  439.         if(loc_type == 0)
  440.         {
  441.             printf("no loc info !!\n");
  442.             return;
  443.         }

  444.         res = dwarf_attr(org_die, DW_AT_type, &t_attr, &error);
  445.         if (res == DW_DLV_OK) // 确定变量的类型以及长度
  446.             get_type(dbg, t_attr, &arr, &points, &type, &type_len);

  447.         if(type == 0)
  448.         {
  449.             printf("error in get_type \n ");
  450.             return;
  451.         }
  452.         if(type == 255)
  453.         {
  454.             printf("DW_TAG_subroutine_type !! \n");
  455.             return;
  456.         }
  457.         tmp = (struct var*) malloc(sizeof(struct var));//申请新的var结构体存放变量信息
  458.         if (tmp)
  459.         {
  460.             memset(tmp,0,sizeof(struct var));
  461.             if(name)
  462.                 memcpy(tmp->name,name,strlen(name)>8?8:strlen(name));
  463.             tmp->array = arr;
  464.             tmp->points = points;
  465.             tmp->type = type;
  466.             tmp->len = type_len;
  467.             tmp->loc_type = loc_type;
  468.             tmp->loc = loc;
  469.             *tmp_loc = tmp;
  470.         }
  471.     }
  472. }
  473. /*******************************************************************************
  474.   *函数名称:static void get_die_and_siblings(Dwarf_Debug dbg, Dwarf_Die in_die,int in_level)
  475.   *函数功能:递归遍历整个DWARF调试信息树,取出其中的变量、寄存器偏移和变量信息
  476.   *输入参数:
  477.     @Dwarf_Debug dbg:libdwarf库的总数据结构
  478.     @Dwarf_Die in_die:需要被遍历的头一个die
  479.     @int in_level:便利处于第几层
  480.   *输出参数:
  481.   *函数返回值:
  482.   *其他:
  483. *******************************************************************************/
  484. static void get_die_and_siblings(Dwarf_Debug dbg, Dwarf_Die in_die,
  485.         int in_level) {
  486.     int res = DW_DLV_ERROR;
  487.     Dwarf_Die cur_die = in_die;
  488.     Dwarf_Die child = 0;
  489.     Dwarf_Error error;
  490.     Dwarf_Half tag;
  491.     Dwarf_Attribute t_attr;
  492.     Dwarf_Unsigned inline_tag;
  493.     Dwarf_Die sib_die = 0;
  494.     struct var *t_var , *p_var;
  495.     struct sub *t_sub , *p_sub;
  496.     struct todo
  497.     {
  498.         Dwarf_Die d;
  499.         Dwarf_Half tag;
  500.         struct todo *n;
  501.     }*todo_list,*t_todo,*p_todo;

  502.     todo_list = NULL;
  503.     for(;;)
  504.     {
  505.         res = dwarf_tag(cur_die, &tag, &error); // 取标签
  506.         if (res != DW_DLV_OK) {
  507.             printf("Error in dwarf_tag , level %d \n", in_level);
  508.             exit(1);
  509.         }
  510.         if(in_level == 1) //由于标准C不允许函数嵌套定义,SO ,1层只有全局变量和函数顶层
  511.         {
  512.             if(tag == DW_TAG_variable) //全局变量
  513.             {
  514.                 print_variable(dbg, cur_die, &t_var);
  515.                 if(asd.global) //放进全局链结尾去
  516.                 {
  517.                     p_var = asd.global;
  518.                     while(p_var->next)
  519.                         p_var = p_var->next;
  520.                     p_var->next = t_var;
  521.                 }
  522.                 else
  523.                     asd.global = t_var;
  524.             }
  525.             if(tag == DW_TAG_subprogram) //函数,判断是否时inline 然后加进SUB链 然后进child取局部变量和包含的块和inlined
  526.             {
  527.                 res = dwarf_attr(cur_die, DW_AT_inline, &t_attr, &error);
  528.                 if(res == DW_DLV_OK)
  529.                 {
  530.                     res = dwarf_formudata(t_attr, &inline_tag, &error);
  531.                     if(res != DW_DLV_OK)
  532.                         exit(1);
  533.                     if(inline_tag == DW_INL_inlined || inline_tag == DW_INL_declared_inlined)
  534.                         goto next_sib;//是inline函数 就出去继续循环 后面把非inline函数加进SUB
  535.                 }
  536.                 print_subprog(dbg, cur_die, &t_sub);
  537.                 if(t_sub)
  538.                 {
  539.                     if(is_new_cu)
  540.                     {
  541.                         is_new_cu = 0;
  542.                         cu_low_pc = t_sub->low_pc;
  543.                     }
  544.                     t_sub->level = in_level;
  545.                     t_sub->type = DW_TAG_subprogram;
  546.                     get_loc_list(dbg, cur_die, t_sub); //把loc信息添加进去
  547.                     if(asd.sub_link) //放进sub链结尾去
  548.                     {
  549.                         p_sub = asd.sub_link;
  550.                         while(p_sub->next)
  551.                             p_sub = p_sub->next;
  552.                         p_sub->next = t_sub;
  553.                     }
  554.                     else
  555.                         asd.sub_link = t_sub;

  556.                     res = dwarf_child(cur_die, &child, &error);
  557.                     if (res == DW_DLV_ERROR)
  558.                     {
  559.                         printf("Error in dwarf_child , level %d \n", in_level);
  560.                         exit(1);
  561.                     }
  562.                     if (res == DW_DLV_OK)
  563.                         get_die_and_siblings(dbg, child, in_level + 1); //进入child 也就是>1的层
  564.                 }
  565.             }
  566.         }
  567.         else if(in_level > 1) //大于1层的地方只有局部变量和块、inlined
  568.         {
  569.             if (tag == DW_TAG_formal_parameter || tag == DW_TAG_variable) //局部变量,挂到sub链最后一个的VAR指针上
  570.             {
  571.                 print_variable(dbg, cur_die, &t_var);
  572.                 p_sub = asd.sub_link;
  573.                 while(p_sub->next)
  574.                     p_sub = p_sub->next;
  575.                 if(p_sub->var)
  576.                 {
  577.                     p_var = p_sub->var;
  578.                     while(p_var->next)
  579.                         p_var = p_var->next;
  580.                     p_var->next = t_var;
  581.                 }
  582.                 else
  583.                     p_sub->var = t_var;
  584.             }
  585.             if(tag == DW_TAG_lexical_block || tag == DW_TAG_inlined_subroutine) // 先放到todo_list里面在for外面单独处理
  586.             {
  587.                 t_todo = (struct todo *) malloc(sizeof(struct todo));
  588.                 if(t_todo)
  589.                 {
  590.                     memset(t_todo,0,sizeof(struct todo));
  591.                     t_todo->d = cur_die;
  592.                     t_todo->tag = tag;
  593.                     if(todo_list)
  594.                     {
  595.                         p_todo = todo_list;
  596.                         while(p_todo->n)
  597.                             p_todo = p_todo->n;
  598.                         p_todo->n = t_todo;
  599.                     }
  600.                     else
  601.                         todo_list = t_todo;
  602.                 }
  603.             }
  604.         }
  605.         else
  606.         {//0层是变编译头信息,没啥用就直接进child
  607.             res = dwarf_child(cur_die, &child, &error);
  608.             if (res == DW_DLV_ERROR)
  609.             {
  610.                 printf("Error in dwarf_child , level %d \n", in_level);
  611.                 exit(1);
  612.             }
  613.             if (res == DW_DLV_OK)
  614.             {
  615.                 is_new_cu = 1;
  616.                 get_die_and_siblings(dbg, child, in_level + 1);
  617.             }
  618.         }
  619.         next_sib:
  620.         sib_die = 0;
  621.         res = dwarf_siblingof(dbg, cur_die, &sib_die, &error);
  622.         if (res == DW_DLV_ERROR) {
  623.             printf("Error in dwarf_siblingof , level %d \n", in_level);
  624.             exit(1);
  625.         }
  626.         if (res == DW_DLV_NO_ENTRY)
  627.             break;

  628.         if (cur_die != in_die && in_level < 2)
  629.             dwarf_dealloc(dbg, cur_die, DW_DLA_DIE);

  630.         cur_die = sib_die;
  631.     }
  632.     if(todo_list)
  633.     {
  634.         t_todo = p_todo = todo_list;
  635.         todo_list = NULL;
  636.         while(p_todo)
  637.         {
  638.             print_subprog(dbg, p_todo->d, &t_sub);
  639.             if(t_sub)
  640.             {
  641.                 t_sub->level = in_level;
  642.                 t_sub->type = p_todo->tag;
  643.                 if(asd.sub_link) //放进sub链结尾去
  644.                 {
  645.                     p_sub = asd.sub_link;
  646.                     while(p_sub->next)
  647.                         p_sub = p_sub->next;
  648.                     p_sub->next = t_sub;
  649.                 }
  650.                 else
  651.                     exit(1); //若在这里asd.sub_link依然为空,那么肯定是有错误了,因为只有在>1的时候才能进到这里

  652.                 res = dwarf_child(cur_die, &child, &error);
  653.                 if (res == DW_DLV_ERROR)
  654.                 {
  655.                     printf("Error in dwarf_child , level %d \n", in_level);
  656.                     exit(1);
  657.                 }
  658.                 if (res == DW_DLV_OK)
  659.                     get_die_and_siblings(dbg, child, in_level + 1); //进入child
  660.             }
  661.             p_todo = p_todo->n;
  662.             dwarf_dealloc(dbg, t_todo->d , DW_DLA_DIE);
  663.             free(t_todo);
  664.             t_todo = p_todo;
  665.         }
  666.     }
  667. }

  668. /*******************************************************************************
  669.   *函数名称:static void read_cu_list(Dwarf_Debug dbg)
  670.   *函数功能:遍历调试信息中包含的全部CU头,提取其中的信息
  671.   *输入参数:
  672.     @Dwarf_Debug dbg:libdwarf库的总数据结构
  673.   *输出参数:
  674.   *函数返回值:
  675.   *其他:
  676. *******************************************************************************/
  677. static void read_cu_list(Dwarf_Debug dbg) {//一次取出一个CU头
  678.     Dwarf_Unsigned cu_header_length = 0;
  679.     Dwarf_Half version_stamp = 0;
  680.     Dwarf_Unsigned abbrev_offset = 0;
  681.     Dwarf_Half address_size = 0;
  682.     Dwarf_Unsigned next_cu_header = 0;
  683.     Dwarf_Error error;

  684.     for (;;) {
  685.         Dwarf_Die no_die = 0;
  686.         Dwarf_Die cu_die = 0;
  687.         int res = DW_DLV_ERROR;
  688.         res = dwarf_next_cu_header(dbg, &cu_header_length, &version_stamp,
  689.                 &abbrev_offset, &address_size, &next_cu_header, &error);//取出一个CU
  690.         if (res == DW_DLV_ERROR) {
  691.             printf("Error in dwarf_next_cu_header\n");
  692.             exit(1);
  693.         }
  694.         if (res == DW_DLV_NO_ENTRY) {
  695.             /* Done. */
  696.             return;
  697.         }
  698.         /* The CU will have a single sibling, a cu_die. */
  699.         res = dwarf_siblingof(dbg, no_die, &cu_die, &error);
  700.         if (res == DW_DLV_ERROR) {
  701.             printf("Error in dwarf_siblingof on CU die \n");
  702.             exit(1);
  703.         }
  704.         if (res == DW_DLV_NO_ENTRY) {
  705.             /* Impossible case. */
  706.             printf("no entry! in dwarf_siblingof on CU die \n");
  707.             exit(1);
  708.         }
  709.         get_die_and_siblings(dbg, cu_die, 0);//拿到CU后,进入第0层,开始递归遍历
  710.         dwarf_dealloc(dbg, cu_die, DW_DLA_DIE);
  711.     }
  712. }
  713. /*******************************************************************************
  714.   *函数名称:static void save_to_file(char *path, struct info *asd)
  715.   *函数功能:将全局链表中存放的调试信息保存到文件中
  716.   *输入参数:
  717.     @char *path:保存文件的路径
  718.     @struct info *asd:要保存的信息所在的链表
  719.   *输出参数:
  720.   *函数返回值:
  721.   *其他:
  722. *******************************************************************************/
  723. static void save_to_file(char *path, struct info *asd)
  724. {
  725.     FILE * f ,* fpos;
  726.     char buf[255];
  727.     static const int size[] =
  728.     {
  729.             sizeof(struct sub) - 3 * sizeof(void *),
  730.             sizeof(struct loc) - sizeof(void *),
  731.             sizeof(struct var) - sizeof(void *)
  732.     };
  733.     static const unsigned char tag[] =
  734.     {
  735.             0x00,0x01,0x02,0x03
  736.     };
  737.     struct sub *p_sub_1, *p_sub_2;
  738.     struct loc *p_loc_1, *p_loc_2;
  739.     struct var *p_var_1, *p_var_2;

  740.     unsigned int pos;
  741.     pos = 0;
  742.     sprintf(buf,"%s.pos",path);//索引文件文件名
  743.     f = fopen(path,"w");//打开调试信息文件
  744.     fpos = fopen(buf,"w");//打开索引文件
  745.     if(f)
  746.     {
  747.         p_var_1 = asd->global;
  748.         while(p_var_1)
  749.         {//首先保存全局变量信息到调试信息文件
  750.             fwrite(tag+3, 1, 1, f);
  751.             fwrite(p_var_1, size[2], 1, f);
  752.             fwrite(tag, 1, 1, f);
  753.             p_var_2 = p_var_1;
  754.             p_var_1 = p_var_1->next;
  755.             free(p_var_2);
  756.             pos += size[2] + 2;
  757.         }
  758.         fwrite(&pos,4,1,fpos);//记录全局变量信息长度到索引文件
  759.         asd->global = NULL;
  760.         p_sub_1 = asd->sub_link;
  761.         while(p_sub_1)
  762.         {//保存变量信息
  763.             fwrite(tag+1, 1, 1, f);
  764.             fwrite(p_sub_1, size[0], 1, f);
  765.             fwrite(tag, 1, 1, f);
  766.             fwrite(&p_sub_1->low_pc, sizeof(long), 1, fpos);//函数的开始地址写入索引文件
  767.             fwrite(&p_sub_1->high_pc, sizeof(long), 1, fpos);//函数的解释地址写入索引文件
  768.             fwrite(&pos,4,1,fpos);//函数在调试信息文件中的位置,写入索引文件
  769.             pos += size[0] + 2;
  770.             p_loc_1 = p_sub_1->loc;
  771.             while(p_loc_1)
  772.             {//变量执行期间寄存偏移情况
  773.                 fwrite(tag+2, 1, 1, f);
  774.                 fwrite(p_loc_1, size[1], 1, f);
  775.                 fwrite(tag, 1, 1, f);
  776.                 p_loc_2 = p_loc_1;
  777.                 p_loc_1 = p_loc_1->next;
  778.                 free(p_loc_2);
  779.                 pos += size[1] + 2;
  780.             }
  781.             p_var_1 = p_sub_1->var;
  782.             while(p_var_1)
  783.             {//函数的局部变量
  784.                 fwrite(tag+3, 1, 1, f);
  785.                 fwrite(p_var_1, size[2], 1, f);
  786.                 fwrite(tag, 1, 1, f);
  787.                 p_var_2 = p_var_1;
  788.                 p_var_1 = p_var_1->next;
  789.                 free(p_var_2);
  790.                 pos += size[2] + 2;
  791.             }
  792.             p_sub_2 = p_sub_1;
  793.             p_sub_1 = p_sub_1->next;
  794.             free(p_sub_2);
  795.         }
  796.         asd->sub_link = NULL;
  797.         fclose(f);//关闭,完成
  798.         fclose(fpos);
  799.     }
  800. }
  801. /*//一些测试函数
  802. static void read_from_file(char *path, struct info *asd)
  803. {//读取出来看文件是否正确
  804.     FILE * f;
  805.     static const int size[] =
  806.     {
  807.             sizeof(struct sub) - 3 * sizeof(void *),
  808.             sizeof(struct loc) - sizeof(void *),
  809.             sizeof(struct var) - sizeof(void *)
  810.     };

  811.     struct sub *p_sub_1, *p_sub_2;
  812.     struct loc *p_loc_1, *p_loc_2;
  813.     struct var *p_var_1, *p_var_2;
  814.     char t;
  815.     int is_global = 1;

  816.     f = fopen(path,"r");
  817.     if(f)
  818.     {
  819.         while(!feof(f))
  820.         {
  821.             fread(&t, 1, 1, f);
  822.             switch(t)
  823.             {
  824.             case 3:
  825.                 p_var_2 = (struct var *) malloc(sizeof(struct var));
  826.                 if(p_var_2)
  827.                 {
  828.                     memset(p_var_2, 0, sizeof(struct var));
  829.                     fread(p_var_2, size[2], 1, f);
  830.                     if(is_global)
  831.                     {
  832.                         if(asd->global)
  833.                         {
  834.                             p_var_1 = asd->global;
  835.                             while(p_var_1 ->next)
  836.                                 p_var_1 = p_var_1->next;
  837.                             p_var_1->next = p_var_2;
  838.                         }
  839.                         else
  840.                             asd->global = p_var_2;
  841.                     }
  842.                     else
  843.                     {
  844.                         p_sub_1 = asd->sub_link;
  845.                         while(p_sub_1->next)
  846.                             p_sub_1 = p_sub_1->next;
  847.                         if(p_sub_1->var)
  848.                         {
  849.                             p_var_1 = p_sub_1->var;
  850.                             while(p_var_1 ->next)
  851.                                 p_var_1 = p_var_1->next;
  852.                             p_var_1->next = p_var_2;
  853.                         }
  854.                         else
  855.                             p_sub_1->var = p_var_2;
  856.                     }
  857.                 }
  858.                 break;
  859.             case 1:
  860.                 p_sub_2 = (struct sub *) malloc(sizeof(struct sub));
  861.                 if(p_sub_2)
  862.                 {
  863.                     is_global = 0;
  864.                     memset(p_sub_2, 0, sizeof(struct sub));
  865.                     fread(p_sub_2, size[0], 1, f);
  866.                     if(asd->sub_link)
  867.                     {
  868.                         p_sub_1 = asd->sub_link;
  869.                         while(p_sub_1->next)
  870.                             p_sub_1 = p_sub_1->next;
  871.                         p_sub_1->next = p_sub_2;
  872.                     }
  873.                     else
  874.                         asd->sub_link = p_sub_2;
  875.                 }
  876.                 break;
  877.             case 2:
  878.                 p_loc_2 = (struct loc *) malloc(sizeof(struct loc));
  879.                 if(p_loc_2)
  880.                 {
  881.                     memset(p_loc_2, 0, sizeof(struct loc));
  882.                     fread(p_loc_2, size[1], 1, f);
  883.                     if(!asd->sub_link)
  884.                         exit(1);
  885.                     p_sub_1 = asd->sub_link;
  886.                     while(p_sub_1->next)
  887.                         p_sub_1 = p_sub_1->next;
  888.                     if(p_sub_1->loc)
  889.                     {
  890.                         p_loc_1 = p_sub_1->loc;
  891.                         while(p_loc_1 ->next)
  892.                             p_loc_1 = p_loc_1->next;
  893.                         p_loc_1->next = p_loc_2;
  894.                     }
  895.                     else
  896.                         p_sub_1->loc = p_loc_2;
  897.                 }
  898.                 break;
  899.             }
  900.             fread(&t, 1, 1, f);
  901.             if(t)
  902.                 exit(1);
  903.         }
  904.     }
  905. }

  906. static void print_pos(char *path)
  907. {//打印索引
  908.     FILE * f ,* fp;
  909.     char buf[255], *b,name[9];
  910.     unsigned int *bp;
  911.     int s,sp,pos;
  912.     sprintf(buf,"%s.pos",path);
  913.     f = fopen(path,"r");
  914.     fp = fopen(buf,"r");
  915.     fseek(f,0,2);
  916.     fseek(fp,0,2);
  917.     s = ftell(f);
  918.     sp = ftell(fp);
  919.     b = (char *) malloc(s);
  920.     bp = (unsigned int *) malloc(sp);
  921.     fseek(f,0,0);
  922.     fseek(fp,0,0);
  923.     fread(b,s,1,f);
  924.     fread(bp,s,1,fp);
  925.     fclose(f);
  926.     fclose(fp);
  927.     printf("全局比啊两数据长度:%d\n",*bp);
  928.     pos = 1;
  929.     while(pos < sp/4)
  930.     {
  931.         printf("low: %08x\n",*(bp+pos));
  932.         printf("hig: %08x\n",*(bp+pos+1));
  933.         memset(name,0,9);
  934.         memcpy(name,b+*(bp+pos+2)+1,8);
  935.         printf("name:%s\n",name);
  936.         pos+=3;
  937.     }
  938. }

  939. static void print(struct info asd)
  940. {//打印全部保存的调试信息
  941.     struct sub *p_sub_1;
  942.     struct loc *p_loc_1;
  943.     struct var *p_var_1;
  944.     char n[9];
  945.     p_var_1 = asd.global;
  946.     while(p_var_1)
  947.     {
  948.         memset(n,0,9);
  949.         memcpy(n,p_var_1->name,8);
  950.         printf("< 1 > 变量名: %s\n< 1 > ",n);
  951.         if ( DW_OP_addr == p_var_1->loc_type)
  952.             printf("直接地址: %x \n",(int) p_var_1->loc);
  953.         else if(p_var_1->loc_type >= DW_OP_breg0 && p_var_1->loc_type <= DW_OP_breg31)
  954.             printf("基址寻址: %d (%s)\n", ((int)p_var_1->loc), *(dwarf_regnames_i386+p_var_1->loc_type-DW_OP_breg0));
  955.         else if(p_var_1->loc_type >= DW_OP_reg0 && p_var_1->loc_type <= DW_OP_reg31)
  956.             printf("通用寄存器: reg%d \n",p_var_1->loc - DW_OP_reg0);
  957.         else if(p_var_1->loc_type == DW_OP_fbreg)
  958.             printf("loclist: %d \n",((int)p_var_1->loc));
  959.         else
  960.             printf("Unknow location \n");//不是C的不管丫的
  961.         printf("< %d > 数组: %d\n",1,p_var_1->array);
  962.         printf("< %d > 指针: %d\n",1,p_var_1->points);
  963.         printf("< %d > 类型: %s\n",1,dwarf_base_type[p_var_1->type - 1]);
  964.         printf("< 1 > 大小: %d\n\n",p_var_1->len);
  965.         p_var_1 = p_var_1->next;
  966.     }
  967.     p_sub_1 = asd.sub_link;
  968.     while(p_sub_1)
  969.     {
  970.         p_loc_1 = p_sub_1->loc;
  971.         p_var_1 = p_sub_1->var;
  972.         memset(n,0,9);
  973.         memcpy(n,p_sub_1->name,8);
  974.         printf("< %d >函数名: %s\n",p_sub_1->level,p_sub_1->type == DW_TAG_subprogram?n:"局部块");
  975.         printf("< %d >low_pc : 0x%08x \n",p_sub_1->level,p_sub_1->low_pc);
  976.         printf("< %d >high_pc : 0x%08x \n\n",p_sub_1->level,p_sub_1->high_pc);
  977.         while(p_loc_1)
  978.         {
  979.             printf("< %d > loclist: 0x%08x -- 0x%08x : (%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);
  980.             p_loc_1 = p_loc_1->next;
  981.         }
  982.         while(p_var_1)
  983.         {
  984.             memset(n,0,9);
  985.             memcpy(n,p_var_1->name,8);
  986.             printf("\n< %d > 变量名: %s\n< %d > ",p_sub_1->level+1,n,p_sub_1->level+1);
  987.             if ( DW_OP_addr == p_var_1->loc_type)
  988.                 printf("直接地址: %x \n",(int) p_var_1->loc);
  989.             else if(p_var_1->loc_type >= DW_OP_breg0 && p_var_1->loc_type <= DW_OP_breg31)
  990.                 printf("基址寻址: %d (%s)\n", ((int)p_var_1->loc), *(dwarf_regnames_i386+p_var_1->loc_type-DW_OP_breg0));
  991.             else if(p_var_1->loc_type >= DW_OP_reg0 && p_var_1->loc_type <= DW_OP_reg31)
  992.                 printf("通用寄存器: reg%d \n",p_var_1->loc - DW_OP_reg0);
  993.             else if(p_var_1->loc_type == DW_OP_fbreg)
  994.                 printf("loclist: %d \n",((int)p_var_1->loc));
  995.             else
  996.                 printf("Unknow location \n");//不是C的不管丫的
  997.             printf("< %d > 数组: %d\n",p_sub_1->level+1,p_var_1->array);
  998.             printf("< %d > 指针: %d\n",p_sub_1->level+1,p_var_1->points);
  999.             printf("< %d > 类型: %s\n",p_sub_1->level+1,dwarf_base_type[p_var_1->type - 1]);
  1000.             printf("< %d > 大小: %d\n\n",p_sub_1->level+1,p_var_1->len);
  1001.             p_var_1 = p_var_1->next;
  1002.         }
  1003.         p_sub_1 = p_sub_1->next;
  1004.     }
  1005. }
  1006. */
  1007. int main(int argc, char **argv) {//初始化dbg
  1008.     Dwarf_Debug dbg = 0;
  1009.     int fd = -1;
  1010.     const char *filepath = "";
  1011.     char p[255];
  1012.     int res = DW_DLV_ERROR;
  1013.     Dwarf_Error error;
  1014.     Dwarf_Handler errhand = 0;
  1015.     Dwarf_Ptr errarg = 0;

  1016.     if (argc < 2)
  1017.         fd = 0;
  1018.     else
  1019.     {
  1020.         filepath = argv[1];
  1021.         fd = open(filepath, O_RDONLY);
  1022.     }
  1023.     if (fd <= 0)
  1024.     {
  1025.         printf("Failure attempting to open \"%s\"\n", filepath);
  1026.         exit(1);
  1027.     }
  1028.     res = dwarf_init(fd, DW_DLC_READ, errhand, errarg, &dbg, &error);
  1029.     if (res != DW_DLV_OK) {
  1030.         printf("Giving up, cannot do DWARF processing\n");
  1031.         exit(1);
  1032.     }
  1033.     read_cu_list(dbg);//解析工作
  1034.     res = dwarf_finish(dbg, &error);
  1035.     if (res != DW_DLV_OK) {
  1036.         printf("dwarf_finish failed!\n");
  1037.     }
  1038.     close(fd);
  1039.     sprintf(p,"%s.dwarf",filepath);
  1040.     if(asd.global || asd.sub_link)
  1041.         save_to_file(p,&asd);
  1042.     //read_from_file(p,&asd);
  1043.     //print(asd);
  1044.     //print_pos(p);
  1045.     printf("end \n");
  1046.     return 0;
  1047. }


点击(此处)折叠或打开

  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <fcntl.h>
  4. #include <stdlib.h>
  5. #include <unistd.h>
  6. #include <stdio.h>
  7. #include <errno.h>
  8. #include <string.h>
  9. #include "dwarf.h"
  10. #include "libdwarf.h"

  11. #define printf(line, ...) ; //禁用所有的printf

  12. static const char *const dwarf_regnames_i386[] =
  13. {
  14.   "eax", "ecx", "edx", "ebx",
  15.   "esp", "ebp", "esi", "edi",
  16.   "eip", "eflags", NULL,
  17.   "st0", "st1", "st2", "st3",
  18.   "st4", "st5", "st6", "st7",
  19.   NULL, NULL,
  20.   "xmm0", "xmm1", "xmm2", "xmm3",
  21.   "xmm4", "xmm5", "xmm6", "xmm7",
  22.   "mm0", "mm1", "mm2", "mm3",
  23.   "mm4", "mm5", "mm6", "mm7",
  24.   "fcw", "fsw", "mxcsr",
  25.   "es", "cs", "ss", "ds", "fs", "gs", NULL, NULL,
  26.   "tr", "ldtr"
  27. };//寄存器顺序+名字,从GDB源代码里copy过来的。。。

  28. static const char *const dwarf_base_type[]=
  29. {
  30.     "void",
  31.     "unsigned int", "unsigned char"    ,"short unsigned int",
  32.     "long unsigned int", "signed char", "short int",
  33.     "int", "long long int", "long long unsigned int",
  34.     "long int", "char", "union", "struct"
  35. }; // 11个C基本类型 + 联合体 + 结构体 + void 没了 C就这么多了
  36. #pragma pack(1)
  37. struct sub
  38. {
  39.     char name[8]; //函数名称
  40.     unsigned short level;//函数位于dwarf信息的第几层
  41.     unsigned char type;//返回值类型,对应dwarf_base_type结构
  42.     unsigned int low_pc;//函数的起始地址
  43.     unsigned int high_pc;//函数的结束地址
  44.     struct loc *loc;//函数执行期间寄存器偏移信息
  45.     struct var *var;//函数内的变量信息
  46.     struct sub *next;//指向下一个sub结构的单链表
  47. };

  48. struct loc
  49. {
  50.     unsigned int begin;//偏移开始地址
  51.     unsigned int end;//偏移结束地址
  52.     unsigned char reg;// *data -0x70 对应上面的寄存器表 其实X86 -O0编译也就4、5两个值
  53.     unsigned short base; // *(data+1)便宜值
  54.     struct loc *next;//指向下一个loc结构的单链表
  55. };

  56. struct var
  57. {
  58.     char name[8];//变量名字
  59.     unsigned int array; // 数组长度,0表示不是数组
  60.     unsigned char points; //这个变量是几层指针
  61.     unsigned char type; //变量类型,对应dwarf_base_type结构
  62.     unsigned int len;//变量类型长度
  63.     unsigned char loc_type; //变量地址类型
  64.     unsigned int loc;//变量地址数据,具体含义由loc_type确定
  65.     struct var *next;//指向下一个var结构的单链表
  66. };

  67. struct info
  68. {
  69.     struct sub * sub_link;//解析过程保存函数链表
  70.     struct var * global;//解析过程中保存全局变量链表
  71. };
  72. #pragma pack()

  73. struct info asd; ///// 在内存中以链表形式保存提取到的信息

  74. unsigned int cu_low_pc;//当前正在处理的编译单元的起始地址
  75. int is_new_cu;//进入新的编译单元
  76. /*******************************************************************************
  77.   *函数名称:static void get_addr(Dwarf_Attribute attr, Dwarf_Addr *val)
  78.   *函数功能:提取直接地址类型属性条目中保存的地址
  79.   *输入参数:
  80.     @Dwarf_Attribute attr:地址类型属性条目
  81.   *输出参数:
  82.     @Dwarf_Addr *val:条目中包含的地址
  83.   *函数返回值:
  84.   *其他:
  85. *******************************************************************************/
  86. static void get_addr(Dwarf_Attribute attr, Dwarf_Addr *val) {
  87.     Dwarf_Error error = 0;
  88.     int res;
  89.     Dwarf_Addr uval = 0;
  90.     res = dwarf_formaddr(attr, &uval, &error);
  91.     if (res == DW_DLV_OK)
  92.         *val = uval;
  93. }
  94. /*******************************************************************************
  95.   *函数名称:static struct sub *new_sub(char* name,unsigned int low,unsigned int high)
  96.   *函数功能:申请一个函数信息块内存空间,并赋值
  97.   *输入参数:
  98.     @char* name:函数的名称
  99.     @unsigned int low:函数的起始地址
  100.     @unsigned int high:函数的结束地址
  101.   *输出参数:
  102.   *函数返回值:struct sub *:申请的信息块地址
  103.   *其他:
  104. *******************************************************************************/
  105. static struct sub *new_sub(char* name,unsigned int low,unsigned int high)
  106. {
  107.     struct sub *tmp_sub = NULL;
  108.     tmp_sub = (struct sub*) malloc(sizeof(struct sub));//申请地址
  109.     if(tmp_sub)//成功的话,填充结构体信息
  110.     {
  111.         memset(tmp_sub,0,sizeof(struct sub));
  112.         if(name)
  113.             memcpy(tmp_sub->name,name,strlen(name)>8?8:strlen(name));
  114.         tmp_sub->low_pc = low;
  115.         tmp_sub->high_pc = high;
  116.         return tmp_sub;
  117.     }
  118.     else//失败返回空
  119.         return NULL;
  120. }
  121. /*******************************************************************************
  122.   *函数名称:static void get_loc_list(Dwarf_Debug dbg, Dwarf_Die die, struct sub *sub)
  123.   *函数功能:解析一个函数类型die的下挂的寄存器偏移信息,保存到sub->loc链表中
  124.   *输入参数:
  125.     @Dwarf_Debug dbg:libdwarf库的总数据结构
  126.     @Dwarf_Die die:需要被解析的一个函数类型die
  127.     @struct sub *sub:函数DIE对应的信息块指针
  128.   *输出参数:
  129.   *函数返回值:
  130.   *其他:dwarf_ 开头的函数都是libdwarf库提供的函数
  131. *******************************************************************************/
  132. static void get_loc_list(Dwarf_Debug dbg, Dwarf_Die die, struct sub *sub)
  133. {
  134.     Dwarf_Unsigned offset=0;
  135.     Dwarf_Error error = 0;
  136.     Dwarf_Addr hipc_off;
  137.     Dwarf_Addr lopc_off;
  138.     Dwarf_Ptr data;
  139.     Dwarf_Unsigned entry_len;
  140.     Dwarf_Error err;
  141.     int res;
  142.     Dwarf_Unsigned next_entry;
  143.     Dwarf_Attribute t_attr;
  144.     struct loc *tmp=NULL,*pos;

  145.     res = dwarf_attr(die, DW_AT_frame_base, &t_attr, &error);//使用libdwarf库解析条目属性
  146.     if (res == DW_DLV_OK)
  147.     {
  148.         res = dwarf_formudata(t_attr, &offset, &error);//使用libdwarf库获取属性对应的条目链
  149.         if (res == DW_DLV_OK)
  150.             for(;;)
  151.                 {
  152.                     res = dwarf_get_loclist_entry(dbg,offset,&hipc_off,&lopc_off,&data,&entry_len,&next_entry,&err);//遍历所有条目
  153.                     if (res == DW_DLV_OK)
  154.                     {//每成功取出一个条目
  155.                         if(entry_len == 0 )
  156.                             break;
  157.                         if(entry_len > 1 )
  158.                         {
  159.                         tmp = (struct loc*) malloc(sizeof(struct loc));//申请内存
  160.                         if(tmp)
  161.                         {
  162.                             memset(tmp,0,sizeof(struct loc));
  163.                             tmp ->begin = cu_low_pc + lopc_off;
  164.                             tmp ->end = cu_low_pc + hipc_off;
  165.                             tmp ->reg = (unsigned short)*(char*)data;//保存条目信息
  166.                             if(entry_len == 2)
  167.                                 tmp ->base = (unsigned short)*(char *)(data+1);
  168.                             else
  169.                                 tmp ->base = (unsigned short)*(unsigned short *)(data+1);
  170.                             if(sub->loc)
  171.                             {
  172.                                 pos = sub->loc;//加入当前处理的函数的loc链表中
  173.                                 while(pos->next)
  174.                                     pos = pos->next;
  175.                                 pos->next = tmp;
  176.                             }
  177.                             else
  178.                                 sub->loc = tmp;
  179.                         }
  180.                         else break;
  181.                         }
  182.                         offset = next_entry;
  183.                         continue;
  184.                     }
  185.                     else break;
  186.                 }
  187.     }
  188. }
  189. /*******************************************************************************
  190.   *函数名称:static Dwarf_Die get_die(Dwarf_Debug dbg, Dwarf_Attribute attr, Dwarf_Half* tag)
  191.   *函数功能:通过偏移量取die和对应的标签
  192.   *输入参数:
  193.     @Dwarf_Debug dbg:libdwarf库的总数据结构
  194.     @Dwarf_Attribute attr:需要被操作的属性结构
  195.     @Dwarf_Half* tag:偏移值
  196.   *输出参数:
  197.   *函数返回值:Dwarf_Die:找到的DIE的指针
  198.   *其他:dwarf_ 开头的函数都是libdwarf库提供的函数
  199. *******************************************************************************/
  200. static Dwarf_Die get_die(Dwarf_Debug dbg, Dwarf_Attribute attr, Dwarf_Half* tag) {//通过偏移量取die和对应的标签
  201.     Dwarf_Error error = 0;
  202.     int res;
  203.     Dwarf_Off offset;
  204.     Dwarf_Die typeDie = 0;
  205.     res = dwarf_global_formref(attr, &offset, &error);
  206.     if (res == DW_DLV_OK) {
  207.         res = dwarf_offdie(dbg, offset, &typeDie, &error);
  208.         if (res == DW_DLV_OK) {
  209.             res = dwarf_tag(typeDie, tag, &error);
  210.             if (res == DW_DLV_OK) {
  211.                 return typeDie;
  212.             }
  213.         }
  214.     }
  215.     return NULL ;
  216. }
  217. /*******************************************************************************
  218.   *函数名称:static void print_subprog(Dwarf_Debug dbg, Dwarf_Die die, struct sub **tmp_sub)
  219.   *函数功能:解析一个函数类型die的全部信息,保存到tmp_sub中
  220.   *输入参数:
  221.     @Dwarf_Debug dbg:libdwarf库的总数据结构
  222.     @Dwarf_Die die:需要被解析的一个函数类型die
  223.   *输出参数:
  224.     @struct sub **tmp_sub:返回函数信息块指针
  225.   *函数返回值:
  226.   *其他:
  227. *******************************************************************************/
  228. static void print_subprog(Dwarf_Debug dbg, Dwarf_Die die, struct sub **tmp_sub) {
  229.     int res;
  230.     Dwarf_Error error = 0;
  231.     Dwarf_Addr lowpc = 0;
  232.     Dwarf_Addr highpc = 0;
  233.     Dwarf_Attribute t_attr;
  234.     Dwarf_Half tag;
  235.     Dwarf_Die org_die = NULL;
  236.     char *name;
  237.     res = dwarf_attr(die, DW_AT_abstract_origin, &t_attr, &error);
  238.     if (res == DW_DLV_OK)
  239.         org_die = get_die(dbg, t_attr, &tag);
  240.     else org_die = die;
  241.     res = dwarf_diename(org_die, &name, &error);//获取函数的名称
  242.     if (res != DW_DLV_OK) {
  243.         name = NULL;
  244.     }
  245.     res = dwarf_attr(die, DW_AT_low_pc, &t_attr, &error);
  246.     if (res == DW_DLV_OK) // 获取函数的开始地址
  247.         get_addr(t_attr, &lowpc);
  248.     res = dwarf_attr(die, DW_AT_high_pc, &t_attr, &error);
  249.     if (res == DW_DLV_OK) // 获取函数的结束地址
  250.         get_addr(t_attr, &highpc);
  251.     *tmp_sub = new_sub(name,(unsigned int)lowpc,(unsigned int)highpc);//申请新的sub结构
  252.     //目前只考虑32位的,unsigned int就行
  253.     //}
  254. }

  255. /*******************************************************************************
  256.   *函数名称:static int get_array_length(Dwarf_Debug dbg, Dwarf_Die die, int *length)
  257.   *函数功能:计算一个数组属性的DIE对应的数组的具体长度
  258.   *输入参数:
  259.     @Dwarf_Debug dbg:libdwarf库的总数据结构
  260.     @Dwarf_Die die:需要被计算的die
  261.   *输出参数:
  262.     @int *length:返回长度值
  263.   *函数返回值:
  264.   *其他:
  265. *******************************************************************************/
  266. static int get_array_length(Dwarf_Debug dbg, Dwarf_Die die, int *length) {//数组类型的长度。。
  267.     int res;
  268.     Dwarf_Error error;
  269.     Dwarf_Die child;
  270.     Dwarf_Attribute tmp;
  271.     res = dwarf_child(die, &child, &error);
  272.     *length = 1;
  273.     Dwarf_Unsigned utmp;
  274.     if (res == DW_DLV_OK) {
  275.         while (1) {
  276.             res = dwarf_attr(child, DW_AT_upper_bound, &tmp, &error);
  277.             if (res == DW_DLV_OK) {
  278.                 res = dwarf_formudata(tmp, &utmp, &error);
  279.                 if (res != DW_DLV_OK)
  280.                     return DW_DLV_ERROR;
  281.                 else
  282.                     *length *= (utmp + 1);
  283.             }
  284.             res = dwarf_siblingof(dbg, child, &child, &error);
  285.             if (res == DW_DLV_ERROR)
  286.                 return DW_DLV_ERROR;
  287.             if (res == DW_DLV_NO_ENTRY)
  288.                 return DW_DLV_OK;
  289.         }
  290.     }
  291.     return DW_DLV_ERROR;
  292. }
  293. /*******************************************************************************
  294.   *函数名称:static void get_type(Dwarf_Debug dbg, Dwarf_Attribute attr, unsigned int *arr, unsigned short *points, unsigned short *type, unsigned int *type_len)
  295.   *函数功能:解析一个变量类型描述类型die的全部信息
  296.   *输入参数:
  297.     @Dwarf_Debug dbg:libdwarf库的总数据结构
  298.     @DDwarf_Attribute attr:需要被解析的一个变量类型die
  299.   *输出参数:
  300.     @unsigned int *arr:是否是数组类型,以及数组长度
  301.     @unsigned short *points:是否时指针类型,以及指针深度,和arr同时非0,表明是一个指针数组,目前不考虑这种情况
  302.     @unsigned short *type:具体类型值,定义对应最上面dwarf_base_type数组
  303.     @unsigned int *type_len:类型长度
  304.   *函数返回值:
  305.   *其他:具体参见DWARF Debugging Information Format.pdf文档中“类型条目”书签标记的位置
  306.        简单来说,attr是个类型描述的开头,他指向一个属性链条,每个点上保存一个属性,便利这个链条确定最终的类型
  307. *******************************************************************************/
  308. static void get_type(Dwarf_Debug dbg, Dwarf_Attribute attr, unsigned int *arr, unsigned short *points, unsigned short *type, unsigned int *type_len) {
  309.     char *name = 0;
  310.     Dwarf_Half tag;
  311.     Dwarf_Unsigned size;
  312.     Dwarf_Error error = 0;
  313.     Dwarf_Attribute t_attr;
  314.     int res;
  315.     int length;
  316.     Dwarf_Die typeDie = get_die(dbg, attr, &tag);
  317.     if (typeDie) {
  318.         switch (tag) {//只处理了和标准C相关的类型
  319.         case DW_TAG_subroutine_type://函数指针,对比没意义,就不管了
  320.             *type = 255;
  321.             break;
  322.         case DW_TAG_typedef://对应C语言中typedef关键字
  323.             goto next_type;
  324.         case DW_TAG_const_type://对应C语言中const关键字
  325.             goto next_type;
  326.         case DW_TAG_pointer_type://对应C语言中变量定义中的 * 指针符
  327.             *points += 1;
  328.             goto next_type;
  329.         case DW_TAG_volatile_type://对应C语言中volatile关键字
  330.             next_type: res = dwarf_attr(typeDie, DW_AT_type, &t_attr, &error);
  331.             if (res == DW_DLV_OK) {
  332.                 get_type(dbg, t_attr, arr, points, type, type_len);
  333.             } else
  334.                 *type = 1;
  335.             break;
  336.         case DW_TAG_base_type://对应dwarf_base_type定义的C基本变量类型
  337.             res = dwarf_diename(typeDie, &name, &error);
  338.             if (res == DW_DLV_OK) {
  339.                 for(res = 0;res<sizeof(dwarf_base_type)/sizeof(char *);res++)
  340.                     if(!strncmp(name,dwarf_base_type[res],strlen(dwarf_base_type[res])))
  341.                     {
  342.                         *type = res+1;
  343.                         break;
  344.                     }
  345.                 res = dwarf_bytesize(typeDie, &size, &error);
  346.                 if (res == DW_DLV_OK) {
  347.                     *type_len = ((unsigned int)size);
  348.                 } else
  349.                     *type_len = 0;
  350.             } else
  351.                 *type = 0;
  352.             break;
  353.         case DW_TAG_array_type://对应C语言中的数组定义
  354.             res = get_array_length(dbg, typeDie, &length);
  355.             if (res == DW_DLV_OK)
  356.                 *arr = length;
  357.             goto next_type;
  358.         case DW_TAG_union_type://对应C语言中联合体定义
  359.             *type = sizeof(dwarf_base_type)/sizeof(char *) -1;
  360.             goto get_size;
  361.         case DW_TAG_structure_type://对应C语言中结构体定义
  362.             *type = sizeof(dwarf_base_type)/sizeof(char *);
  363.             get_size: res = dwarf_bytesize(typeDie, &size, &error);
  364.             if (res == DW_DLV_OK)
  365.                 *type_len = (unsigned int)size;
  366.             else
  367.                 *type_len = 0;
  368.             break;
  369.         default://非C语言类型
  370.             *type = 0;
  371.             break;
  372.         }
  373.     }
  374. }
  375. /*******************************************************************************
  376.   *函数名称:static void get_location(Dwarf_Debug dbg, Dwarf_Attribute attr, unsigned int *loc_type, unsigned int *loc)
  377.   *函数功能:解析一个地址类型die的全部信息
  378.   *输入参数:
  379.     @Dwarf_Debug dbg:libdwarf库的总数据结构
  380.     @Dwarf_Attribute attr:需要被解析的一个地址类型die
  381.   *输出参数:
  382.     @unsigned int *loc_type:返回die标签包含的地址的地址类型
  383.     @unsigned int *loc:返回die标签包含的地址的具体地址数值
  384.   *函数返回值:
  385.   *其他:地址类型和地址数值包含[直接地址:32位线性地址][寄存器基址寻址:偏移值]等多个可能的赋值含义组合
  386.      具体参见DWARF Debugging Information Format.pdf文档中“位置描述”书签标记的位置
  387. *******************************************************************************/
  388. static void get_location(Dwarf_Debug dbg, Dwarf_Attribute attr, unsigned int *loc_type, unsigned int *loc) {
  389.     Dwarf_Error error = 0;
  390.     int res;
  391.     Dwarf_Locdesc *llbuf;
  392.     Dwarf_Signed lcnt;
  393.     res = dwarf_loclist(attr, &llbuf, &lcnt, &error);
  394.     if (res == DW_DLV_OK) {
  395.         *loc_type = (unsigned int) llbuf->ld_s->lr_atom;
  396.         *loc = (unsigned int)llbuf->ld_s->lr_number;
  397.         dwarf_dealloc(dbg, llbuf->ld_s, DW_DLA_LOC_BLOCK);
  398.         dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC);
  399.     }
  400. }
  401. /*******************************************************************************
  402.   *函数名称:static void print_variable(Dwarf_Debug dbg, Dwarf_Die die, struct var ** tmp_loc)
  403.   *函数功能:解析一个变量类型die的全部信息,保存到tmp_loc中
  404.   *输入参数:
  405.     @Dwarf_Debug dbg:libdwarf库的总数据结构
  406.     @Dwarf_Die die:需要被解析的一个变量类型die
  407.   *输出参数:
  408.     @struct var ** tmp_loc:返回变量信息块指针
  409.   *函数返回值:
  410.   *其他:
  411. *******************************************************************************/
  412. static void print_variable(Dwarf_Debug dbg, Dwarf_Die die, struct var ** tmp_loc) {
  413.     int res;
  414.     Dwarf_Error error = 0;
  415.     Dwarf_Attribute t_attr;
  416.     unsigned int arr, type_len, loc_type, loc;
  417.     unsigned short points, type ;
  418.     struct var * tmp =NULL ;
  419.     Dwarf_Die org_die = NULL;
  420.     Dwarf_Half tag;
  421.     char *name;

  422.     *tmp_loc = tmp;
  423.     res = dwarf_attr(die, DW_AT_abstract_origin, &t_attr, &error);
  424.     if (res == DW_DLV_OK)
  425.         org_die = get_die(dbg, t_attr, &tag);
  426.     else org_die = die;
  427.     res = dwarf_diename(org_die, &name, &error);
  428.     if (res != DW_DLV_OK) {
  429.         name = NULL;
  430.     }

  431.     res = dwarf_attr(die, DW_AT_declaration, &t_attr, &error);
  432.     if (res != DW_DLV_OK) { //若res == DW_DLV_OK,则是extern变量,没有位置信息,就不再保存
  433.         loc_type = loc =0;
  434.         arr = type_len = 0;
  435.         points = type = 0;

  436.         res = dwarf_attr(die, DW_AT_location, &t_attr, &error);
  437.         if (res == DW_DLV_OK) //获取变量的位置信息
  438.             get_location(dbg, t_attr, &loc_type, &loc);

  439.         if(loc_type == 0)
  440.         {
  441.             printf("no loc info !!\n");
  442.             return;
  443.         }

  444.         res = dwarf_attr(org_die, DW_AT_type, &t_attr, &error);
  445.         if (res == DW_DLV_OK) // 确定变量的类型以及长度
  446.             get_type(dbg, t_attr, &arr, &points, &type, &type_len);

  447.         if(type == 0)
  448.         {
  449.             printf("error in get_type \n ");
  450.             return;
  451.         }
  452.         if(type == 255)
  453.         {
  454.             printf("DW_TAG_subroutine_type !! \n");
  455.             return;
  456.         }
  457.         tmp = (struct var*) malloc(sizeof(struct var));//申请新的var结构体存放变量信息
  458.         if (tmp)
  459.         {
  460.             memset(tmp,0,sizeof(struct var));
  461.             if(name)
  462.                 memcpy(tmp->name,name,strlen(name)>8?8:strlen(name));
  463.             tmp->array = arr;
  464.             tmp->points = points;
  465.             tmp->type = type;
  466.             tmp->len = type_len;
  467.             tmp->loc_type = loc_type;
  468.             tmp->loc = loc;
  469.             *tmp_loc = tmp;
  470.         }
  471.     }
  472. }
  473. /*******************************************************************************
  474.   *函数名称:static void get_die_and_siblings(Dwarf_Debug dbg, Dwarf_Die in_die,int in_level)
  475.   *函数功能:递归遍历整个DWARF调试信息树,取出其中的变量、寄存器偏移和变量信息
  476.   *输入参数:
  477.     @Dwarf_Debug dbg:libdwarf库的总数据结构
  478.     @Dwarf_Die in_die:需要被遍历的头一个die
  479.     @int in_level:便利处于第几层
  480.   *输出参数:
  481.   *函数返回值:
  482.   *其他:
  483. *******************************************************************************/
  484. static void get_die_and_siblings(Dwarf_Debug dbg, Dwarf_Die in_die,
  485.         int in_level) {
  486.     int res = DW_DLV_ERROR;
  487.     Dwarf_Die cur_die = in_die;
  488.     Dwarf_Die child = 0;
  489.     Dwarf_Error error;
  490.     Dwarf_Half tag;
  491.     Dwarf_Attribute t_attr;
  492.     Dwarf_Unsigned inline_tag;
  493.     Dwarf_Die sib_die = 0;
  494.     struct var *t_var , *p_var;
  495.     struct sub *t_sub , *p_sub;
  496.     struct todo
  497.     {
  498.         Dwarf_Die d;
  499.         Dwarf_Half tag;
  500.         struct todo *n;
  501.     }*todo_list,*t_todo,*p_todo;

  502.     todo_list = NULL;
  503.     for(;;)
  504.     {
  505.         res = dwarf_tag(cur_die, &tag, &error); // 取标签
  506.         if (res != DW_DLV_OK) {
  507.             printf("Error in dwarf_tag , level %d \n", in_level);
  508.             exit(1);
  509.         }
  510.         if(in_level == 1) //由于标准C不允许函数嵌套定义,SO ,1层只有全局变量和函数顶层
  511.         {
  512.             if(tag == DW_TAG_variable) //全局变量
  513.             {
  514.                 print_variable(dbg, cur_die, &t_var);
  515.                 if(asd.global) //放进全局链结尾去
  516.                 {
  517.                     p_var = asd.global;
  518.                     while(p_var->next)
  519.                         p_var = p_var->next;
  520.                     p_var->next = t_var;
  521.                 }
  522.                 else
  523.                     asd.global = t_var;
  524.             }
  525.             if(tag == DW_TAG_subprogram) //函数,判断是否时inline 然后加进SUB链 然后进child取局部变量和包含的块和inlined
  526.             {
  527.                 res = dwarf_attr(cur_die, DW_AT_inline, &t_attr, &error);
  528.                 if(res == DW_DLV_OK)
  529.                 {
  530.                     res = dwarf_formudata(t_attr, &inline_tag, &error);
  531.                     if(res != DW_DLV_OK)
  532.                         exit(1);
  533.                     if(inline_tag == DW_INL_inlined || inline_tag == DW_INL_declared_inlined)
  534.                         goto next_sib;//是inline函数 就出去继续循环 后面把非inline函数加进SUB
  535.                 }
  536.                 print_subprog(dbg, cur_die, &t_sub);
  537.                 if(t_sub)
  538.                 {
  539.                     if(is_new_cu)
  540.                     {
  541.                         is_new_cu = 0;
  542.                         cu_low_pc = t_sub->low_pc;
  543.                     }
  544.                     t_sub->level = in_level;
  545.                     t_sub->type = DW_TAG_subprogram;
  546.                     get_loc_list(dbg, cur_die, t_sub); //把loc信息添加进去
  547.                     if(asd.sub_link) //放进sub链结尾去
  548.                     {
  549.                         p_sub = asd.sub_link;
  550.                         while(p_sub->next)
  551.                             p_sub = p_sub->next;
  552.                         p_sub->next = t_sub;
  553.                     }
  554.                     else
  555.                         asd.sub_link = t_sub;

  556.                     res = dwarf_child(cur_die, &child, &error);
  557.                     if (res == DW_DLV_ERROR)
  558.                     {
  559.                         printf("Error in dwarf_child , level %d \n", in_level);
  560.                         exit(1);
  561.                     }
  562.                     if (res == DW_DLV_OK)
  563.                         get_die_and_siblings(dbg, child, in_level + 1); //进入child 也就是>1的层
  564.                 }
  565.             }
  566.         }
  567.         else if(in_level > 1) //大于1层的地方只有局部变量和块、inlined
  568.         {
  569.             if (tag == DW_TAG_formal_parameter || tag == DW_TAG_variable) //局部变量,挂到sub链最后一个的VAR指针上
  570.             {
  571.                 print_variable(dbg, cur_die, &t_var);
  572.                 p_sub = asd.sub_link;
  573.                 while(p_sub->next)
  574.                     p_sub = p_sub->next;
  575.                 if(p_sub->var)
  576.                 {
  577.                     p_var = p_sub->var;
  578.                     while(p_var->next)
  579.                         p_var = p_var->next;
  580.                     p_var->next = t_var;
  581.                 }
  582.                 else
  583.                     p_sub->var = t_var;
  584.             }
  585.             if(tag == DW_TAG_lexical_block || tag == DW_TAG_inlined_subroutine) // 先放到todo_list里面在for外面单独处理
  586.             {
  587.                 t_todo = (struct todo *) malloc(sizeof(struct todo));
  588.                 if(t_todo)
  589.                 {
  590.                     memset(t_todo,0,sizeof(struct todo));
  591.                     t_todo->d = cur_die;
  592.                     t_todo->tag = tag;
  593.                     if(todo_list)
  594.                     {
  595.                         p_todo = todo_list;
  596.                         while(p_todo->n)
  597.                             p_todo = p_todo->n;
  598.                         p_todo->n = t_todo;
  599.                     }
  600.                     else
  601.                         todo_list = t_todo;
  602.                 }
  603.             }
  604.         }
  605.         else
  606.         {//0层是变编译头信息,没啥用就直接进child
  607.             res = dwarf_child(cur_die, &child, &error);
  608.             if (res == DW_DLV_ERROR)
  609.             {
  610.                 printf("Error in dwarf_child , level %d \n", in_level);
  611.                 exit(1);
  612.             }
  613.             if (res == DW_DLV_OK)
  614.             {
  615.                 is_new_cu = 1;
  616.                 get_die_and_siblings(dbg, child, in_level + 1);
  617.             }
  618.         }
  619.         next_sib:
  620.         sib_die = 0;
  621.         res = dwarf_siblingof(dbg, cur_die, &sib_die, &error);
  622.         if (res == DW_DLV_ERROR) {
  623.             printf("Error in dwarf_siblingof , level %d \n", in_level);
  624.             exit(1);
  625.         }
  626.         if (res == DW_DLV_NO_ENTRY)
  627.             break;

  628.         if (cur_die != in_die && in_level < 2)
  629.             dwarf_dealloc(dbg, cur_die, DW_DLA_DIE);

  630.         cur_die = sib_die;
  631.     }
  632.     if(todo_list)
  633.     {
  634.         t_todo = p_todo = todo_list;
  635.         todo_list = NULL;
  636.         while(p_todo)
  637.         {
  638.             print_subprog(dbg, p_todo->d, &t_sub);
  639.             if(t_sub)
  640.             {
  641.                 t_sub->level = in_level;
  642.                 t_sub->type = p_todo->tag;
  643.                 if(asd.sub_link) //放进sub链结尾去
  644.                 {
  645.                     p_sub = asd.sub_link;
  646.                     while(p_sub->next)
  647.                         p_sub = p_sub->next;
  648.                     p_sub->next = t_sub;
  649.                 }
  650.                 else
  651.                     exit(1); //若在这里asd.sub_link依然为空,那么肯定是有错误了,因为只有在>1的时候才能进到这里

  652.                 res = dwarf_child(cur_die, &child, &error);
  653.                 if (res == DW_DLV_ERROR)
  654.                 {
  655.                     printf("Error in dwarf_child , level %d \n", in_level);
  656.                     exit(1);
  657.                 }
  658.                 if (res == DW_DLV_OK)
  659.                     get_die_and_siblings(dbg, child, in_level + 1); //进入child
  660.             }
  661.             p_todo = p_todo->n;
  662.             dwarf_dealloc(dbg, t_todo->d , DW_DLA_DIE);
  663.             free(t_todo);
  664.             t_todo = p_todo;
  665.         }
  666.     }
  667. }

  668. /*******************************************************************************
  669.   *函数名称:static void read_cu_list(Dwarf_Debug dbg)
  670.   *函数功能:遍历调试信息中包含的全部CU头,提取其中的信息
  671.   *输入参数:
  672.     @Dwarf_Debug dbg:libdwarf库的总数据结构
  673.   *输出参数:
  674.   *函数返回值:
  675.   *其他:
  676. *******************************************************************************/
  677. static void read_cu_list(Dwarf_Debug dbg) {//一次取出一个CU头
  678.     Dwarf_Unsigned cu_header_length = 0;
  679.     Dwarf_Half version_stamp = 0;
  680.     Dwarf_Unsigned abbrev_offset = 0;
  681.     Dwarf_Half address_size = 0;
  682.     Dwarf_Unsigned next_cu_header = 0;
  683.     Dwarf_Error error;

  684.     for (;;) {
  685.         Dwarf_Die no_die = 0;
  686.         Dwarf_Die cu_die = 0;
  687.         int res = DW_DLV_ERROR;
  688.         res = dwarf_next_cu_header(dbg, &cu_header_length, &version_stamp,
  689.                 &abbrev_offset, &address_size, &next_cu_header, &error);//取出一个CU
  690.         if (res == DW_DLV_ERROR) {
  691.             printf("Error in dwarf_next_cu_header\n");
  692.             exit(1);
  693.         }
  694.         if (res == DW_DLV_NO_ENTRY) {
  695.             /* Done. */
  696.             return;
  697.         }
  698.         /* The CU will have a single sibling, a cu_die. */
  699.         res = dwarf_siblingof(dbg, no_die, &cu_die, &error);
  700.         if (res == DW_DLV_ERROR) {
  701.             printf("Error in dwarf_siblingof on CU die \n");
  702.             exit(1);
  703.         }
  704.         if (res == DW_DLV_NO_ENTRY) {
  705.             /* Impossible case. */
  706.             printf("no entry! in dwarf_siblingof on CU die \n");
  707.             exit(1);
  708.         }
  709.         get_die_and_siblings(dbg, cu_die, 0);//拿到CU后,进入第0层,开始递归遍历
  710.         dwarf_dealloc(dbg, cu_die, DW_DLA_DIE);
  711.     }
  712. }
  713. /*******************************************************************************
  714.   *函数名称:static void save_to_file(char *path, struct info *asd)
  715.   *函数功能:将全局链表中存放的调试信息保存到文件中
  716.   *输入参数:
  717.     @char *path:保存文件的路径
  718.     @struct info *asd:要保存的信息所在的链表
  719.   *输出参数:
  720.   *函数返回值:
  721.   *其他:
  722. *******************************************************************************/
  723. static void save_to_file(char *path, struct info *asd)
  724. {
  725.     FILE * f ,* fpos;
  726.     char buf[255];
  727.     static const int size[] =
  728.     {
  729.             sizeof(struct sub) - 3 * sizeof(void *),
  730.             sizeof(struct loc) - sizeof(void *),
  731.             sizeof(struct var) - sizeof(void *)
  732.     };
  733.     static const unsigned char tag[] =
  734.     {
  735.             0x00,0x01,0x02,0x03
  736.     };
  737.     struct sub *p_sub_1, *p_sub_2;
  738.     struct loc *p_loc_1, *p_loc_2;
  739.     struct var *p_var_1, *p_var_2;

  740.     unsigned int pos;
  741.     pos = 0;
  742.     sprintf(buf,"%s.pos",path);//索引文件文件名
  743.     f = fopen(path,"w");//打开调试信息文件
  744.     fpos = fopen(buf,"w");//打开索引文件
  745.     if(f)
  746.     {
  747.         p_var_1 = asd->global;
  748.         while(p_var_1)
  749.         {//首先保存全局变量信息到调试信息文件
  750.             fwrite(tag+3, 1, 1, f);
  751.             fwrite(p_var_1, size[2], 1, f);
  752.             fwrite(tag, 1, 1, f);
  753.             p_var_2 = p_var_1;
  754.             p_var_1 = p_var_1->next;
  755.             free(p_var_2);
  756.             pos += size[2] + 2;
  757.         }
  758.         fwrite(&pos,4,1,fpos);//记录全局变量信息长度到索引文件
  759.         asd->global = NULL;
  760.         p_sub_1 = asd->sub_link;
  761.         while(p_sub_1)
  762.         {//保存变量信息
  763.             fwrite(tag+1, 1, 1, f);
  764.             fwrite(p_sub_1, size[0], 1, f);
  765.             fwrite(tag, 1, 1, f);
  766.             fwrite(&p_sub_1->low_pc, sizeof(long), 1, fpos);//函数的开始地址写入索引文件
  767.             fwrite(&p_sub_1->high_pc, sizeof(long), 1, fpos);//函数的解释地址写入索引文件
  768.             fwrite(&pos,4,1,fpos);//函数在调试信息文件中的位置,写入索引文件
  769.             pos += size[0] + 2;
  770.             p_loc_1 = p_sub_1->loc;
  771.             while(p_loc_1)
  772.             {//变量执行期间寄存偏移情况
  773.                 fwrite(tag+2, 1, 1, f);
  774.                 fwrite(p_loc_1, size[1], 1, f);
  775.                 fwrite(tag, 1, 1, f);
  776.                 p_loc_2 = p_loc_1;
  777.                 p_loc_1 = p_loc_1->next;
  778.                 free(p_loc_2);
  779.                 pos += size[1] + 2;
  780.             }
  781.             p_var_1 = p_sub_1->var;
  782.             while(p_var_1)
  783.             {//函数的局部变量
  784.                 fwrite(tag+3, 1, 1, f);
  785.                 fwrite(p_var_1, size[2], 1, f);
  786.                 fwrite(tag, 1, 1, f);
  787.                 p_var_2 = p_var_1;
  788.                 p_var_1 = p_var_1->next;
  789.                 free(p_var_2);
  790.                 pos += size[2] + 2;
  791.             }
  792.             p_sub_2 = p_sub_1;
  793.             p_sub_1 = p_sub_1->next;
  794.             free(p_sub_2);
  795.         }
  796.         asd->sub_link = NULL;
  797.         fclose(f);//关闭,完成
  798.         fclose(fpos);
  799.     }
  800. }
  801. /*//一些测试函数
  802. static void read_from_file(char *path, struct info *asd)
  803. {//读取出来看文件是否正确
  804.     FILE * f;
  805.     static const int size[] =
  806.     {
  807.             sizeof(struct sub) - 3 * sizeof(void *),
  808.             sizeof(struct loc) - sizeof(void *),
  809.             sizeof(struct var) - sizeof(void *)
  810.     };

  811.     struct sub *p_sub_1, *p_sub_2;
  812.     struct loc *p_loc_1, *p_loc_2;
  813.     struct var *p_var_1, *p_var_2;
  814.     char t;
  815.     int is_global = 1;

  816.     f = fopen(path,"r");
  817.     if(f)
  818.     {
  819.         while(!feof(f))
  820.         {
  821.             fread(&t, 1, 1, f);
  822.             switch(t)
  823.             {
  824.             case 3:
  825.                 p_var_2 = (struct var *) malloc(sizeof(struct var));
  826.                 if(p_var_2)
  827.                 {
  828.                     memset(p_var_2, 0, sizeof(struct var));
  829.                     fread(p_var_2, size[2], 1, f);
  830.                     if(is_global)
  831.                     {
  832.                         if(asd->global)
  833.                         {
  834.                             p_var_1 = asd->global;
  835.                             while(p_var_1 ->next)
  836.                                 p_var_1 = p_var_1->next;
  837.                             p_var_1->next = p_var_2;
  838.                         }
  839.                         else
  840.                             asd->global = p_var_2;
  841.                     }
  842.                     else
  843.                     {
  844.                         p_sub_1 = asd->sub_link;
  845.                         while(p_sub_1->next)
  846.                             p_sub_1 = p_sub_1->next;
  847.                         if(p_sub_1->var)
  848.                         {
  849.                             p_var_1 = p_sub_1->var;
  850.                             while(p_var_1 ->next)
  851.                                 p_var_1 = p_var_1->next;
  852.                             p_var_1->next = p_var_2;
  853.                         }
  854.                         else
  855.                             p_sub_1->var = p_var_2;
  856.                     }
  857.                 }
  858.                 break;
  859.             case 1:
  860.                 p_sub_2 = (struct sub *) malloc(sizeof(struct sub));
  861.                 if(p_sub_2)
  862.                 {
  863.                     is_global = 0;
  864.                     memset(p_sub_2, 0, sizeof(struct sub));
  865.                     fread(p_sub_2, size[0], 1, f);
  866.                     if(asd->sub_link)
  867.                     {
  868.                         p_sub_1 = asd->sub_link;
  869.                         while(p_sub_1->next)
  870.                             p_sub_1 = p_sub_1->next;
  871.                         p_sub_1->next = p_sub_2;
  872.                     }
  873.                     else
  874.                         asd->sub_link = p_sub_2;
  875.                 }
  876.                 break;
  877.             case 2:
  878.                 p_loc_2 = (struct loc *) malloc(sizeof(struct loc));
  879.                 if(p_loc_2)
  880.                 {
  881.                     memset(p_loc_2, 0, sizeof(struct loc));
  882.                     fread(p_loc_2, size[1], 1, f);
  883.                     if(!asd->sub_link)
  884.                         exit(1);
  885.                     p_sub_1 = asd->sub_link;
  886.                     while(p_sub_1->next)
  887.                         p_sub_1 = p_sub_1->next;
  888.                     if(p_sub_1->loc)
  889.                     {
  890.                         p_loc_1 = p_sub_1->loc;
  891.                         while(p_loc_1 ->next)
  892.                             p_loc_1 = p_loc_1->next;
  893.                         p_loc_1->next = p_loc_2;
  894.                     }
  895.                     else
  896.                         p_sub_1->loc = p_loc_2;
  897.                 }
  898.                 break;
  899.             }
  900.             fread(&t, 1, 1, f);
  901.             if(t)
  902.                 exit(1);
  903.         }
  904.     }
  905. }

  906. static void print_pos(char *path)
  907. {//打印索引
  908.     FILE * f ,* fp;
  909.     char buf[255], *b,name[9];
  910.     unsigned int *bp;
  911.     int s,sp,pos;
  912.     sprintf(buf,"%s.pos",path);
  913.     f = fopen(path,"r");
  914.     fp = fopen(buf,"r");
  915.     fseek(f,0,2);
  916.     fseek(fp,0,2);
  917.     s = ftell(f);
  918.     sp = ftell(fp);
  919.     b = (char *) malloc(s);
  920.     bp = (unsigned int *) malloc(sp);
  921.     fseek(f,0,0);
  922.     fseek(fp,0,0);
  923.     fread(b,s,1,f);
  924.     fread(bp,s,1,fp);
  925.     fclose(f);
  926.     fclose(fp);
  927.     printf("全局比啊两数据长度:%d\n",*bp);
  928.     pos = 1;
  929.     while(pos < sp/4)
  930.     {
  931.         printf("low: %08x\n",*(bp+pos));
  932.         printf("hig: %08x\n",*(bp+pos+1));
  933.         memset(name,0,9);
  934.         memcpy(name,b+*(bp+pos+2)+1,8);
  935.         printf("name:%s\n",name);
  936.         pos+=3;
  937.     }
  938. }

  939. static void print(struct info asd)
  940. {//打印全部保存的调试信息
  941.     struct sub *p_sub_1;
  942.     struct loc *p_loc_1;
  943.     struct var *p_var_1;
  944.     char n[9];
  945.     p_var_1 = asd.global;
  946.     while(p_var_1)
  947.     {
  948.         memset(n,0,9);
  949.         memcpy(n,p_var_1->name,8);
  950.         printf("< 1 > 变量名: %s\n< 1 > ",n);
  951.         if ( DW_OP_addr == p_var_1->loc_type)
  952.             printf("直接地址: %x \n",(int) p_var_1->loc);
  953.         else if(p_var_1->loc_type >= DW_OP_breg0 && p_var_1->loc_type <= DW_OP_breg31)
  954.             printf("基址寻址: %d (%s)\n", ((int)p_var_1->loc), *(dwarf_regnames_i386+p_var_1->loc_type-DW_OP_breg0));
  955.         else if(p_var_1->loc_type >= DW_OP_reg0 && p_var_1->loc_type <= DW_OP_reg31)
  956.             printf("通用寄存器: reg%d \n",p_var_1->loc - DW_OP_reg0);
  957.         else if(p_var_1->loc_type == DW_OP_fbreg)
  958.             printf("loclist: %d \n",((int)p_var_1->loc));
  959.         else
  960.             printf("Unknow location \n");//不是C的不管丫的
  961.         printf("< %d > 数组: %d\n",1,p_var_1->array);
  962.         printf("< %d > 指针: %d\n",1,p_var_1->points);
  963.         printf("< %d > 类型: %s\n",1,dwarf_base_type[p_var_1->type - 1]);
  964.         printf("< 1 > 大小: %d\n\n",p_var_1->len);
  965.         p_var_1 = p_var_1->next;
  966.     }
  967.     p_sub_1 = asd.sub_link;
  968.     while(p_sub_1)
  969.     {
  970.         p_loc_1 = p_sub_1->loc;
  971.         p_var_1 = p_sub_1->var;
  972.         memset(n,0,9);
  973.         memcpy(n,p_sub_1->name,8);
  974.         printf("< %d >函数名: %s\n",p_sub_1->level,p_sub_1->type == DW_TAG_subprogram?n:"局部块");
  975.         printf("< %d >low_pc : 0x%08x \n",p_sub_1->level,p_sub_1->low_pc);
  976.         printf("< %d >high_pc : 0x%08x \n\n",p_sub_1->level,p_sub_1->high_pc);
  977.         while(p_loc_1)
  978.         {
  979.             printf("< %d > loclist: 0x%08x -- 0x%08x : (%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);
  980.             p_loc_1 = p_loc_1->next;
  981.         }
  982.         while(p_var_1)
  983.         {
  984.             memset(n,0,9);
  985.             memcpy(n,p_var_1->name,8);
  986.             printf("\n< %d > 变量名: %s\n< %d > ",p_sub_1->level+1,n,p_sub_1->level+1);
  987.             if ( DW_OP_addr == p_var_1->loc_type)
  988.                 printf("直接地址: %x \n",(int) p_var_1->loc);
  989.             else if(p_var_1->loc_type >= DW_OP_breg0 && p_var_1->loc_type <= DW_OP_breg31)
  990.                 printf("基址寻址: %d (%s)\n", ((int)p_var_1->loc), *(dwarf_regnames_i386+p_var_1->loc_type-DW_OP_breg0));
  991.             else if(p_var_1->loc_type >= DW_OP_reg0 && p_var_1->loc_type <= DW_OP_reg31)
  992.                 printf("通用寄存器: reg%d \n",p_var_1->loc - DW_OP_reg0);
  993.             else if(p_var_1->loc_type == DW_OP_fbreg)
  994.                 printf("loclist: %d \n",((int)p_var_1->loc));
  995.             else
  996.                 printf("Unknow location \n");//不是C的不管丫的
  997.             printf("< %d > 数组: %d\n",p_sub_1->level+1,p_var_1->array);
  998.             printf("< %d > 指针: %d\n",p_sub_1->level+1,p_var_1->points);
  999.             printf("< %d > 类型: %s\n",p_sub_1->level+1,dwarf_base_type[p_var_1->type - 1]);
  1000.             printf("< %d > 大小: %d\n\n",p_sub_1->level+1,p_var_1->len);
  1001.             p_var_1 = p_var_1->next;
  1002.         }
  1003.         p_sub_1 = p_sub_1->next;
  1004.     }
  1005. }
  1006. */
  1007. int main(int argc, char **argv) {//初始化dbg
  1008.     Dwarf_Debug dbg = 0;
  1009.     int fd = -1;
  1010.     const char *filepath = "";
  1011.     char p[255];
  1012.     int res = DW_DLV_ERROR;
  1013.     Dwarf_Error error;
  1014.     Dwarf_Handler errhand = 0;
  1015.     Dwarf_Ptr errarg = 0;

  1016.     if (argc < 2)
  1017.         fd = 0;
  1018.     else
  1019.     {
  1020.         filepath = argv[1];
  1021.         fd = open(filepath, O_RDONLY);
  1022.     }
  1023.     if (fd <= 0)
  1024.     {
  1025.         printf("Failure attempting to open \"%s\"\n", filepath);
  1026.         exit(1);
  1027.     }
  1028.     res = dwarf_init(fd, DW_DLC_READ, errhand, errarg, &dbg, &error);
  1029.     if (res != DW_DLV_OK) {
  1030.         printf("Giving up, cannot do DWARF processing\n");
  1031.         exit(1);
  1032.     }
  1033.     read_cu_list(dbg);//解析工作
  1034.     res = dwarf_finish(dbg, &error);
  1035.     if (res != DW_DLV_OK) {
  1036.         printf("dwarf_finish failed!\n");
  1037.     }
  1038.     close(fd);
  1039.     sprintf(p,"%s.dwarf",filepath);
  1040.     if(asd.global || asd.sub_link)
  1041.         save_to_file(p,&asd);
  1042.     //read_from_file(p,&asd);
  1043.     //print(asd);
  1044.     //print_pos(p);
  1045.     printf("end \n");
  1046.     return 0;
  1047. }

阅读(2793) | 评论(0) | 转发(0) |
1

上一篇:笔试题(2)

下一篇:链表

给主人留下些什么吧!~~