home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / swtools / libdwarf / pro_die.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  9.1 KB  |  332 lines

  1. /*
  2.     pro_die.c
  3.     $Revision: 1.12 $    $Date: 1993/09/30 17:03:31 $    
  4.     $Source: /cmplrs.src/v4.00/libdwarf/RCS/pro_die.c,v $
  5.  
  6.     Contains die related routines 
  7.  
  8. */
  9.  
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include "pro_incl.h"
  13.  
  14.  
  15. /* adds an attribute to a die */
  16. void _dwarf_pro_add_at_to_die(Dwarf_P_Die die, Dwarf_P_Attribute attr);
  17.  
  18. /*----------------------------------------------------------------------------
  19.     This function creates a new die. 
  20.     tag: tag of the new die to be created
  21.     parent,child,left,right: specify neighbors of the new die. Only
  22.         one of these may be non-null
  23. -----------------------------------------------------------------------------*/
  24. Dwarf_P_Die
  25. dwarf_new_die(
  26.     Dwarf_P_Debug dbg,
  27.     Dwarf_Tag tag,
  28.     Dwarf_P_Die parent,
  29.     Dwarf_P_Die child,
  30.     Dwarf_P_Die left,
  31.     Dwarf_P_Die right,
  32.     Dwarf_Error *error)
  33. {
  34.     Dwarf_P_Die new_die, ret_die;
  35.     int n_nulls;
  36.  
  37.     new_die = (Dwarf_P_Die) 
  38.         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Die_s));
  39.     if (new_die == NULL) {
  40.         DWARF_P_DBG_ERROR(dbg,DW_DLE_DIE_ALLOC,(Dwarf_P_Die)DW_DLV_BADADDR);
  41.     }
  42.     new_die->di_parent = NULL;
  43.     new_die->di_left = NULL;
  44.     new_die->di_right = NULL;
  45.     new_die->di_child = NULL;
  46.     new_die->di_tag = tag;
  47.     ret_die = dwarf_die_link(new_die,parent,child,left,right,error);
  48.     return ret_die;
  49. }
  50.  
  51. /*----------------------------------------------------------------------------
  52.     This function links up a die to specified neighbors
  53.     parent,child,left,right: specify neighbors of the new die. Only
  54.         one of these may be non-null
  55. -----------------------------------------------------------------------------*/
  56. Dwarf_P_Die
  57. dwarf_die_link(
  58.     Dwarf_P_Die new_die,
  59.     Dwarf_P_Die parent,
  60.     Dwarf_P_Die child,
  61.     Dwarf_P_Die left,
  62.     Dwarf_P_Die right,
  63.     Dwarf_Error *error)
  64. {
  65.     int n_nulls;    /* to count # of non null neighbors */
  66.  
  67.     n_nulls = 0;
  68.     if (parent != NULL) {
  69.         n_nulls++;
  70.         new_die->di_parent = parent;
  71.         if (parent->di_child) {    /* got to traverse the child's siblings */
  72.         Dwarf_P_Die curdie;
  73.  
  74.         curdie = parent->di_child;
  75.         while (curdie->di_right)
  76.             curdie = curdie->di_right;
  77.         curdie->di_right = new_die;    /* attach to sibling list */
  78.         new_die->di_left = curdie;    /* back pointer */
  79.         }
  80.         else 
  81.         parent->di_child = new_die;
  82.     }
  83.     if (child != NULL) {
  84.         n_nulls++;
  85.         new_die->di_child = child;
  86.         if (child->di_parent) {
  87.         DWARF_P_DBG_ERROR(NULL,DW_DLE_PARENT_EXISTS,(Dwarf_P_Die)DW_DLV_BADADDR);
  88.         } else
  89.         child->di_parent = new_die;
  90.     }
  91.     if (left != NULL) {
  92.         n_nulls++;
  93.         new_die->di_left = left;
  94.         if (left->di_right)     /* there's already a right sibl, lets insert */
  95.         new_die->di_right = left->di_right;
  96.         left->di_right = new_die;
  97.         /* add parent pointer */
  98.         if (new_die->di_parent) {
  99.         DWARF_P_DBG_ERROR(NULL,DW_DLE_PARENT_EXISTS,(Dwarf_P_Die)DW_DLV_BADADDR);
  100.         } else
  101.             new_die->di_parent = left->di_parent;
  102.     }
  103.     if (right != NULL) {
  104.         n_nulls++;
  105.         new_die->di_right = right;
  106.         if (right->di_left)        /* left sibl exists, try inserting */
  107.         new_die->di_left = right->di_left;
  108.         right->di_left = new_die;
  109.         if (new_die->di_parent) {
  110.         DWARF_P_DBG_ERROR(NULL,DW_DLE_PARENT_EXISTS,(Dwarf_P_Die)DW_DLV_BADADDR);
  111.         } else
  112.             new_die->di_parent = right->di_parent;
  113.     }
  114.     if (n_nulls > 1) {     /* multiple neighbors, error */
  115.         DWARF_P_DBG_ERROR(NULL,DW_DLE_EXTRA_NEIGHBORS,(Dwarf_P_Die)DW_DLV_BADADDR);
  116.     }
  117.     return new_die;
  118.     
  119. }
  120.  
  121. /*----------------------------------------------------------------------------
  122.     This function adds a die to dbg struct. It should be called using 
  123.     the root of all the dies.
  124. -----------------------------------------------------------------------------*/
  125. Dwarf_Unsigned 
  126. dwarf_add_die_to_debug(
  127.     Dwarf_P_Debug dbg,
  128.     Dwarf_P_Die first_die,
  129.     Dwarf_Error *error)
  130. {
  131.     if (first_die == NULL) {
  132.         DWARF_P_DBG_ERROR(dbg,DW_DLE_DIE_NULL,DW_DLV_NOCOUNT);
  133.     }
  134.     if (first_die->di_tag != DW_TAG_compile_unit) {
  135.         DWARF_P_DBG_ERROR(dbg,DW_DLE_WRONG_TAG,DW_DLV_NOCOUNT);
  136.     }
  137.     dbg->de_dies = first_die;
  138.     return 0;
  139. }
  140.  
  141. int
  142. _dwarf_pro_add_AT_stmt_list( 
  143.     Dwarf_P_Debug dbg,
  144.     Dwarf_P_Die first_die,
  145.     Dwarf_Error *error)
  146. {
  147.     Dwarf_P_Attribute new_attr;
  148.     Dwarf_Unsigned du;
  149.     Dwarf_Word dw;
  150.  
  151.     /*  Add AT_stmt_list attribute */
  152.     du = 0;
  153.     dw = 0;
  154.     new_attr = (Dwarf_P_Attribute)
  155.         _dwarf_p_get_alloc(NULL,sizeof(struct Dwarf_P_Attribute_s));
  156.     if (new_attr == NULL) {
  157.         DWARF_P_DBG_ERROR(NULL,DW_DLE_ATTR_ALLOC,DW_DLV_NOCOUNT);
  158.     }
  159.  
  160.     new_attr->ar_attribute = DW_AT_stmt_list;
  161.     if (IS_64BIT(dbg)) {
  162.         new_attr->ar_attribute_form = DW_FORM_data8;
  163.         new_attr->ar_rel_type = R_MIPS_64;
  164.     }
  165.     else {
  166.         new_attr->ar_attribute_form = DW_FORM_data4;
  167.         new_attr->ar_rel_type = R_MIPS_32;
  168.     }
  169.         
  170.     new_attr->ar_nbytes = sizeof_uword(dbg);
  171.     new_attr->ar_next = NULL;
  172.     new_attr->ar_data = (char *)
  173.         _dwarf_p_get_alloc(NULL, sizeof_uword(dbg));
  174.     if (new_attr->ar_data == NULL) {
  175.         DWARF_P_DBG_ERROR(NULL,DW_DLE_ADDR_ALLOC,DW_DLV_NOCOUNT);
  176.     }
  177.     if (IS_64BIT(dbg)) {
  178.         Dwarf_Unsigned du = 0;
  179.         memcpy((void *)new_attr->ar_data,(const void *)&du,sizeof(Dwarf_Unsigned));
  180.     }
  181.     else {
  182.         Dwarf_Word dw = 0;
  183.         memcpy((void *)new_attr->ar_data,(const void *)&dw,sizeof(Dwarf_Word));
  184.     }
  185.  
  186.     _dwarf_pro_add_at_to_die(first_die,new_attr);
  187.     return 0;
  188. }
  189.  
  190. /*-----------------------------------------------------------------------------
  191.     Add AT_name attribute to die
  192. ------------------------------------------------------------------------------*/
  193. Dwarf_P_Attribute 
  194. dwarf_add_AT_name(
  195.     Dwarf_P_Die die,
  196.     char *name,
  197.     Dwarf_Error *error)
  198. {
  199.     Dwarf_P_Attribute new_attr;
  200.  
  201.     if (die == NULL) {
  202.         DWARF_P_DBG_ERROR(NULL,DW_DLE_DIE_NULL,(Dwarf_P_Attribute)DW_DLV_BADADDR);
  203.     }
  204.     new_attr = (Dwarf_P_Attribute)
  205.         _dwarf_p_get_alloc(NULL,sizeof(struct Dwarf_P_Attribute_s));
  206.     if (new_attr == NULL) {
  207.         DWARF_P_DBG_ERROR(NULL,DW_DLE_ATTR_ALLOC,(Dwarf_P_Attribute)DW_DLV_BADADDR);
  208.     }
  209.  
  210.     /* fill in the information */
  211.     new_attr->ar_attribute = DW_AT_name;
  212.     /* assume that form is string, no debug_str yet */
  213.     new_attr->ar_attribute_form = DW_FORM_string;
  214.     new_attr->ar_nbytes = strlen(name)+1;
  215.     new_attr->ar_next = NULL;
  216.     new_attr->ar_data = (char *)
  217.         _dwarf_p_get_alloc(NULL, strlen(name)+1);
  218.     if (new_attr->ar_data == NULL) {
  219.         DWARF_P_DBG_ERROR(NULL,DW_DLE_STRING_ALLOC,(Dwarf_P_Attribute)DW_DLV_BADADDR);
  220.     }
  221.     strcpy(new_attr->ar_data, name);
  222.  
  223.     new_attr->ar_rel_type = R_MIPS_NONE;
  224.  
  225.     /* add attribute to the die */
  226.     _dwarf_pro_add_at_to_die(die,new_attr);
  227.     return new_attr;
  228. }
  229.  
  230.  
  231. /*-----------------------------------------------------------------------------
  232.     Add AT_comp_dir attribute to die
  233. ------------------------------------------------------------------------------*/
  234. Dwarf_P_Attribute 
  235. dwarf_add_AT_comp_dir (
  236.     Dwarf_P_Die ownerdie,
  237.     char *current_working_directory,
  238.     Dwarf_Error *error)
  239. {
  240.     Dwarf_P_Attribute new_attr;
  241.  
  242.     if (ownerdie == NULL) {
  243.         DWARF_P_DBG_ERROR(NULL,DW_DLE_DIE_NULL,(Dwarf_P_Attribute)DW_DLV_BADADDR);
  244.     }
  245.     new_attr = (Dwarf_P_Attribute)
  246.         _dwarf_p_get_alloc(NULL,sizeof(struct Dwarf_P_Attribute_s));
  247.     if (new_attr == NULL) {
  248.         DWARF_P_DBG_ERROR(NULL,DW_DLE_ATTR_ALLOC,(Dwarf_P_Attribute)DW_DLV_BADADDR);
  249.     }
  250.  
  251.     /* fill in the information */
  252.     new_attr->ar_attribute = DW_AT_comp_dir;
  253.     /* assume that form is string, no debug_str yet */
  254.     new_attr->ar_attribute_form = DW_FORM_string;
  255.     new_attr->ar_nbytes = strlen(current_working_directory)+1;
  256.     new_attr->ar_next = NULL;
  257.     new_attr->ar_data = (char *)
  258.         _dwarf_p_get_alloc(NULL, strlen(current_working_directory)+1);
  259.     if (new_attr->ar_data == NULL) {
  260.         DWARF_P_DBG_ERROR(NULL,DW_DLE_STRING_ALLOC,(Dwarf_P_Attribute)DW_DLV_BADADDR);
  261.     }
  262.     strcpy(new_attr->ar_data, current_working_directory);
  263.  
  264.     new_attr->ar_rel_type = R_MIPS_NONE;
  265.  
  266.     /* add attribute to the die */
  267.     _dwarf_pro_add_at_to_die(ownerdie,new_attr);
  268.     return new_attr;
  269. }
  270.  
  271. int 
  272. _dwarf_pro_add_AT_fde(
  273.     Dwarf_P_Debug dbg, 
  274.     Dwarf_P_Die die, 
  275.     Dwarf_Unsigned offset,
  276.     Dwarf_Error *error)
  277. {
  278.     Dwarf_P_Attribute new_attr;
  279.  
  280.     if (die == NULL) {
  281.          DWARF_P_DBG_ERROR(NULL,DW_DLE_DIE_NULL,-1);
  282.     }
  283.     new_attr = (Dwarf_P_Attribute)
  284.         _dwarf_p_get_alloc(NULL,sizeof(struct Dwarf_P_Attribute_s));
  285.     if (new_attr == NULL) {
  286.         DWARF_P_DBG_ERROR(NULL,DW_DLE_ATTR_ALLOC,-1);
  287.     }
  288.  
  289.     /* fill in the information */
  290.     new_attr->ar_attribute = DW_AT_MIPS_fde;
  291.     if (IS_64BIT(dbg)) {
  292.         new_attr->ar_attribute_form = DW_FORM_data8;
  293.         new_attr->ar_rel_type = R_MIPS_64;
  294.     }
  295.     else {
  296.         new_attr->ar_attribute_form = DW_FORM_data4;
  297.         new_attr->ar_rel_type = R_MIPS_32;
  298.     }
  299.     new_attr->ar_nbytes = sizeof_uword(dbg);
  300.     new_attr->ar_next = NULL;
  301.     new_attr->ar_data = (char *)
  302.         _dwarf_p_get_alloc(NULL, sizeof_uword(dbg));
  303.     if (new_attr->ar_data == NULL) {
  304.         DWARF_P_DBG_ERROR(NULL,DW_DLE_ADDR_ALLOC,DW_DLV_NOCOUNT);
  305.     }
  306.     if (IS_64BIT(dbg)) {
  307.         Dwarf_Unsigned du = offset;
  308.         memcpy((void *)new_attr->ar_data,(const void *)&du,sizeof(Dwarf_Unsigned));
  309.     }
  310.     else {
  311.         Dwarf_Word dw = offset;
  312.         memcpy((void *)new_attr->ar_data,(const void *)&dw,sizeof(Dwarf_Word));
  313.     }
  314.     _dwarf_pro_add_at_to_die(die, new_attr);
  315.  
  316.     return 0;
  317. }
  318.  
  319. void 
  320. _dwarf_pro_add_at_to_die(Dwarf_P_Die die, Dwarf_P_Attribute attr)
  321. {
  322.     if (die->di_last_attr) {
  323.         die->di_last_attr->ar_next = attr;
  324.         die->di_last_attr = attr;
  325.         die->di_n_attr++;
  326.     } 
  327.     else {
  328.         die->di_n_attr = 1;
  329.         die->di_attrs = die->di_last_attr = attr;
  330.     }
  331. }
  332.