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

  1. #include <stdio.h>
  2. #include "dwarf_incl.h"
  3. #include "dwarf_vars.h"
  4.  
  5. int
  6. dwarf_get_vars (
  7.     Dwarf_Debug        dbg,
  8.     Dwarf_Var        **vars,
  9.     Dwarf_Signed       * ret_var_count,
  10.     Dwarf_Error        *error
  11. )
  12. {
  13.     /* Sweeps the complete .debug_varnames section. */
  14.     Dwarf_Small            *varnames_ptr;
  15.  
  16.     Dwarf_Word            length;
  17.  
  18.     /* 
  19.         Points to the context for the current set of variable names,
  20.         and contains information to identify the compilation-unit
  21.         that the set refers to.
  22.     */
  23.     Dwarf_Var_Context        varnames_context;
  24.  
  25.         /* Version number for the current set of variable names. */
  26.     Dwarf_Half            version;
  27.  
  28.     /* 
  29.         Offset from the start of compilation-unit 
  30.         for the current variable .
  31.     */
  32.     Dwarf_Off            cu_offset;
  33.  
  34.     /* Counts the number of variables read. */
  35.     Dwarf_Unsigned        var_count = 0;
  36.  
  37.     /* Points to the current variable read. */
  38.     Dwarf_Var            var;
  39.  
  40.     /* 
  41.         Used to chain the Dwarf_Var_s structs for creating
  42.         contiguous list of pointers to the structs.
  43.     */
  44.     Dwarf_Chain            curr_chain, prev_chain, head_chain = NULL;
  45.  
  46.     /* Points to contiguous block of Dwarf_Var's to be returned. */
  47.     Dwarf_Var            *ret_vars;
  48.  
  49.     /* Temporary counter. */
  50.     Dwarf_Unsigned        i;
  51.  
  52.     /* ***** BEGIN CODE ***** */
  53.  
  54.  
  55.     if (dbg == NULL) 
  56.     {_dwarf_error(NULL, error, DW_DLE_DBG_NULL); return(DW_DLV_ERROR);}
  57.  
  58.     if (dbg->de_debug_varnames == NULL) {
  59.     return(DW_DLV_NO_ENTRY);
  60.     }
  61.  
  62.     varnames_ptr = dbg->de_debug_varnames;
  63.     do {
  64.     varnames_context = (Dwarf_Var_Context)
  65.         _dwarf_get_alloc(dbg, DW_DLA_VAR_CONTEXT, 1);
  66.     if (varnames_context == NULL) {
  67.         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 
  68.         return(DW_DLV_ERROR);
  69.         }
  70.  
  71.     READ_UNALIGNED(length, varnames_ptr, dbg->de_length_size);
  72.     varnames_ptr += dbg->de_length_size;
  73.     varnames_context->vr_length = length;
  74.  
  75.  
  76.     READ_UNALIGNED(version, varnames_ptr, sizeof(Dwarf_Half));
  77.     varnames_ptr += sizeof(Dwarf_Half);
  78.     if (version != CURRENT_VERSION_STAMP) {
  79.         _dwarf_error(dbg, error, DW_DLE_DEBUG_VARNAMES_VERSION_ERROR);
  80.         return(DW_DLV_ERROR);
  81.     }
  82.  
  83.     READ_UNALIGNED(varnames_context->vr_info_offset, varnames_ptr, 
  84.         dbg->de_length_size);
  85.     varnames_ptr += dbg->de_length_size;
  86.     
  87.         /* 
  88.         Add the length of the cu_header to point to the
  89.         DW_TAG_compile_unit die.
  90.         */
  91.     varnames_context->vr_info_offset +=
  92.         dbg->de_length_size +    /* Size of cu length field. */
  93.         sizeof(Dwarf_Half) +    /* Size of version stamp field. */
  94.         dbg->de_length_size +    /* Size of abbrev offset field. */
  95.         sizeof(Dwarf_Small);    /* Size of address size field. */
  96.  
  97.     READ_UNALIGNED(varnames_context->vr_info_length, varnames_ptr, 
  98.         dbg->de_length_size);
  99.     varnames_ptr += dbg->de_length_size;
  100.  
  101.     if (varnames_ptr > dbg->de_debug_varnames +
  102.         dbg->de_debug_varnames_size) {
  103.         _dwarf_error(dbg, error, DW_DLE_DEBUG_VARNAMES_LENGTH_BAD);
  104.         return(DW_DLV_ERROR);
  105.     }
  106.  
  107.     READ_UNALIGNED(cu_offset, varnames_ptr, dbg->de_length_size);
  108.     varnames_ptr += dbg->de_length_size;
  109.  
  110.     while (cu_offset != 0) {
  111.  
  112.             var = (Dwarf_Var)_dwarf_get_alloc(dbg, DW_DLA_VAR, 1);
  113.         if (var == NULL) {
  114.         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 
  115.         return(DW_DLV_ERROR);
  116.         }
  117.         var_count++;
  118.  
  119.         var->va_context = varnames_context;
  120.  
  121.         /* Subtract length of CU header to adjust offsets. */
  122.             var->va_cu_offset = cu_offset -
  123.         dbg->de_length_size -    /* Size of CU length field. */
  124.         sizeof(Dwarf_Half) -    /* Size of version stamp field. */
  125.         dbg->de_length_size -    /* Size of abbrev offset field. */
  126.         sizeof(Dwarf_Small);    /* Size of address size field. */
  127.  
  128.         var->va_name = varnames_ptr;
  129.         varnames_ptr = varnames_ptr + strlen(varnames_ptr) + 1;
  130.  
  131.         READ_UNALIGNED(cu_offset, varnames_ptr, dbg->de_length_size);
  132.         varnames_ptr += dbg->de_length_size;
  133.  
  134.         if (varnames_ptr > dbg->de_debug_varnames + 
  135.         dbg->de_debug_varnames_size) {
  136.         _dwarf_error(dbg, error, DW_DLE_DEBUG_VARNAMES_LENGTH_BAD);
  137.         return(DW_DLV_ERROR);
  138.         }
  139.  
  140.         curr_chain = (Dwarf_Chain)_dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
  141.         if (curr_chain == NULL) {
  142.         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
  143.         return(DW_DLV_ERROR);
  144.         }
  145.  
  146.         /* Put current variable on singly_linked list. */
  147.         curr_chain->ch_item = (Dwarf_Var)var;
  148.         if (head_chain == NULL)
  149.         head_chain = prev_chain = curr_chain;
  150.         else {
  151.         prev_chain->ch_next = curr_chain;
  152.         prev_chain = curr_chain;
  153.         }
  154.     }
  155.  
  156.     } while (varnames_ptr < 
  157.     dbg->de_debug_varnames + dbg->de_debug_varnames_size);
  158.     
  159.     /* Points to contiguous block of Dwarf_Var's. */
  160.     ret_vars = (Dwarf_Var *)
  161.     _dwarf_get_alloc(dbg, DW_DLA_LIST, var_count);
  162.     if (ret_vars == NULL) 
  163.     {_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return(DW_DLV_ERROR);}
  164.  
  165.     /* 
  166.         Store pointers to Dwarf_Var_s structs in
  167.         contiguous block, and deallocate the chain.
  168.     */
  169.     curr_chain = head_chain;
  170.     for (i = 0; i < var_count; i++) {
  171.     *(ret_vars + i) = curr_chain->ch_item;
  172.     prev_chain = curr_chain;
  173.     curr_chain = curr_chain->ch_next;
  174.     dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
  175.     }
  176.  
  177.     *vars = ret_vars;
  178.     *ret_var_count = (var_count);
  179.     return DW_DLV_OK;
  180. }
  181.  
  182.  
  183. int
  184. dwarf_varname (
  185.     Dwarf_Var        var,
  186.     char      **        ret_varname,
  187.     Dwarf_Error        *error
  188. )
  189. {
  190.     if (var == NULL)
  191.     {_dwarf_error(NULL, error, DW_DLE_VAR_NULL); return(DW_DLV_ERROR);}
  192.  
  193.     *ret_varname = (var->va_name);
  194.     return DW_DLV_OK;
  195. }
  196.  
  197.  
  198. int
  199. dwarf_var_die_offset (
  200.     Dwarf_Var        var,
  201.     Dwarf_Off    *       returned_offset,
  202.     Dwarf_Error        *error
  203. )
  204. {
  205.     if (var == NULL) {
  206.      _dwarf_error(NULL, error, DW_DLE_VAR_NULL); 
  207.     return(DW_DLV_ERROR);
  208.     }
  209.  
  210.     if (var->va_context == NULL) {
  211.     _dwarf_error(NULL, error, DW_DLE_VAR_CONTEXT_NULL);
  212.     return(DW_DLV_ERROR);
  213.     }
  214.  
  215.     *returned_offset = (var->va_cu_offset + var->va_context->vr_info_offset);
  216.     return DW_DLV_OK;
  217. }
  218.  
  219.  
  220. int
  221. dwarf_var_cu_offset (
  222.     Dwarf_Var        var,
  223.     Dwarf_Off    *       returned_offset,
  224.     Dwarf_Error        *error
  225. )
  226. {
  227.     if (var == NULL) {
  228.     _dwarf_error(NULL, error, DW_DLE_VAR_NULL); 
  229.     return(DW_DLV_ERROR);
  230.     }
  231.  
  232.     if (var->va_context == NULL) {
  233.     _dwarf_error(NULL, error, DW_DLE_VAR_CONTEXT_NULL);
  234.     return(DW_DLV_ERROR);
  235.     }
  236.  
  237.     *returned_offset = (var->va_context->vr_info_offset);
  238.     return DW_DLV_OK;
  239. }
  240.  
  241.  
  242. int
  243. dwarf_var_name_offsets (
  244.     Dwarf_Var        var,
  245.     char              **returned_name,
  246.     Dwarf_Off        *die_offset,
  247.     Dwarf_Off        *cu_offset,
  248.     Dwarf_Error        *error
  249. )
  250. {
  251.     if (var == NULL) {
  252.     _dwarf_error(NULL, error, DW_DLE_VAR_NULL); 
  253.     return(DW_DLV_ERROR);
  254.     }
  255.  
  256.     if (var->va_context == NULL) {
  257.     _dwarf_error(NULL, error, DW_DLE_VAR_CONTEXT_NULL); 
  258.     return(DW_DLV_ERROR);
  259.     }
  260.  
  261.     if (die_offset != NULL)
  262.     *die_offset = var->va_cu_offset + 
  263.         var->va_context->vr_info_offset;
  264.  
  265.     if (cu_offset != NULL)
  266.     *cu_offset = var->va_context->vr_info_offset;
  267.  
  268.     *returned_name = (var->va_name);
  269.     return DW_DLV_OK;
  270. }
  271.