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

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