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

  1. #include <stdio.h>
  2. #include "dwarf_incl.h"
  3. #include "dwarf_types.h"
  4.  
  5. int
  6. dwarf_get_types (
  7.     Dwarf_Debug        dbg,
  8.     Dwarf_Type        **types,
  9.     Dwarf_Signed    *ret_type_count,
  10.     Dwarf_Error        *error
  11. )
  12. {
  13.     /* Sweeps the complete .debug_typenames section. */
  14.     Dwarf_Small            *typenames_ptr;
  15.  
  16.     Dwarf_Word            length;
  17.  
  18.     /* 
  19.         Points to the context for the current set of type names,
  20.         and contains information to identify the compilation-unit
  21.         that the set refers to.
  22.     */
  23.     Dwarf_Type_Context        typenames_context;
  24.  
  25.         /* Version number for the current set of typenames. */
  26.     Dwarf_Half            version;
  27.  
  28.     /* 
  29.         Offset from the start of compilation-unit 
  30.         for the current type.
  31.     */
  32.     Dwarf_Off            cu_offset;
  33.  
  34.     /* Counts the number of types read. */
  35.     Dwarf_Unsigned        type_count = 0;
  36.  
  37.     /* Points to the current type read. */
  38.     Dwarf_Type            type;
  39.  
  40.     /* 
  41.         Used to chain the Dwarf_Type_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_Type's to be returned. */
  47.     Dwarf_Type            *ret_types;
  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_typenames == NULL) {
  60.     return(DW_DLV_NO_ENTRY);
  61.     }
  62.  
  63.     typenames_ptr = dbg->de_debug_typenames;
  64.     do {
  65.     typenames_context = (Dwarf_Type_Context)
  66.         _dwarf_get_alloc(dbg, DW_DLA_TYPENAME_CONTEXT, 1);
  67.     if (typenames_context == NULL) {
  68.         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 
  69.         return(DW_DLV_ERROR);
  70.     }
  71.  
  72.     READ_UNALIGNED(length, typenames_ptr, dbg->de_length_size);
  73.     typenames_ptr += dbg->de_length_size;
  74.     typenames_context->tp_length = length;
  75.  
  76.  
  77.     READ_UNALIGNED(version, typenames_ptr, sizeof(Dwarf_Half));
  78.     typenames_ptr += sizeof(Dwarf_Half);
  79.     if (version != CURRENT_VERSION_STAMP) {
  80.         _dwarf_error(dbg, error, DW_DLE_DEBUG_TYPENAMES_VERSION_ERROR);
  81.         return(DW_DLV_ERROR);
  82.     }
  83.  
  84.     READ_UNALIGNED(typenames_context->tp_info_offset, typenames_ptr, 
  85.         dbg->de_length_size);
  86.     typenames_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.     typenames_context->tp_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(typenames_context->tp_info_length, typenames_ptr, 
  99.         dbg->de_length_size);
  100.     typenames_ptr += dbg->de_length_size;
  101.  
  102.     if (typenames_ptr > dbg->de_debug_typenames +
  103.         dbg->de_debug_typenames_size) {
  104.         _dwarf_error(dbg, error, DW_DLE_DEBUG_TYPENAMES_LENGTH_BAD);
  105.         return(DW_DLV_ERROR);
  106.     }
  107.  
  108.     READ_UNALIGNED(cu_offset, typenames_ptr, dbg->de_length_size);
  109.     typenames_ptr += dbg->de_length_size;
  110.  
  111.     while (cu_offset != 0) {
  112.  
  113.             type = (Dwarf_Type)_dwarf_get_alloc(dbg, DW_DLA_TYPENAME, 1);
  114.         if (type == NULL) {
  115.         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 
  116.         return(DW_DLV_ERROR);
  117.         }
  118.         type_count++;
  119.  
  120.         type->ty_context = typenames_context;
  121.  
  122.         /* Subtract length of CU header to adjust offsets. */
  123.             type->ty_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.         type->ty_name = typenames_ptr;
  130.         typenames_ptr = typenames_ptr + strlen(typenames_ptr) + 1;
  131.  
  132.         READ_UNALIGNED(cu_offset, typenames_ptr, dbg->de_length_size);
  133.         typenames_ptr += dbg->de_length_size;
  134.  
  135.         if (typenames_ptr > dbg->de_debug_typenames + 
  136.         dbg->de_debug_typenames_size) {
  137.         _dwarf_error(dbg, error, DW_DLE_DEBUG_TYPENAMES_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 type on singly_linked list. */
  148.         curr_chain->ch_item = (Dwarf_Type)type;
  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 (typenames_ptr < 
  158.     dbg->de_debug_typenames + dbg->de_debug_typenames_size);
  159.     
  160.     /* Points to contiguous block of Dwarf_Type's. */
  161.     ret_types = (Dwarf_Type *)
  162.     _dwarf_get_alloc(dbg, DW_DLA_LIST, type_count);
  163.     if (ret_types == NULL) 
  164.     {_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return(DW_DLV_ERROR);}
  165.  
  166.     /* 
  167.         Store pointers to Dwarf_Type_s structs in
  168.         contiguous block, and deallocate the chain.
  169.     */
  170.     curr_chain = head_chain;
  171.     for (i = 0; i < type_count; i++) {
  172.     *(ret_types + 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.     *types = ret_types;
  179.     *ret_type_count = (type_count);
  180.     return DW_DLV_OK;
  181. }
  182.  
  183.  
  184. int
  185. dwarf_typename (
  186.     Dwarf_Type        type,
  187.     char            **  ret_name,
  188.     Dwarf_Error        *error
  189. )
  190. {
  191.     if (type == NULL)
  192.     {_dwarf_error(NULL, error, DW_DLE_TYPE_NULL); return(DW_DLV_ERROR);}
  193.  
  194.     *ret_name = (type->ty_name);
  195.     return DW_DLV_OK;
  196. }
  197.  
  198.  
  199. int
  200. dwarf_type_die_offset (
  201.     Dwarf_Type        type,
  202.     Dwarf_Off        *  ret_offset,
  203.     Dwarf_Error        *error
  204. )
  205. {
  206.     if (type == NULL) 
  207.     {_dwarf_error(NULL, error, DW_DLE_TYPE_NULL); return(DW_DLV_ERROR);}
  208.  
  209.     if (type->ty_context == NULL) {
  210.     _dwarf_error(NULL, error, DW_DLE_TYPE_CONTEXT_NULL);
  211.     return(DW_DLV_ERROR);
  212.     }
  213.  
  214.     *ret_offset = (type->ty_cu_offset + type->ty_context->tp_info_offset);
  215.     return DW_DLV_OK;
  216. }
  217.  
  218.  
  219. int
  220. dwarf_type_cu_offset (
  221.     Dwarf_Type        type,
  222.     Dwarf_Off        *  ret_offset,
  223.     Dwarf_Error        *error
  224. )
  225. {
  226.     if (type == NULL)
  227.     {_dwarf_error(NULL, error, DW_DLE_TYPE_NULL); return(DW_DLV_ERROR);}
  228.  
  229.     if (type->ty_context == NULL) {
  230.     _dwarf_error(NULL, error, DW_DLE_TYPE_CONTEXT_NULL);
  231.     return(DW_DLV_ERROR);
  232.     }
  233.  
  234.     *ret_offset = (type->ty_context->tp_info_offset);
  235.     return DW_DLV_OK;
  236.     
  237. }
  238.  
  239.  
  240. int
  241. dwarf_type_name_offsets (
  242.     Dwarf_Type        type,
  243.     char            **  returned_name,
  244.     Dwarf_Off        *die_offset,
  245.     Dwarf_Off        *cu_offset,
  246.     Dwarf_Error        *error
  247. )
  248. {
  249.     if (type == NULL)
  250.     {_dwarf_error(NULL, error, DW_DLE_TYPE_NULL); return(DW_DLV_ERROR);}
  251.  
  252.     if (type->ty_context == NULL)  {
  253.     _dwarf_error(NULL, error, DW_DLE_TYPE_CONTEXT_NULL); 
  254.     return(DW_DLV_ERROR);
  255.     }
  256.  
  257.     if (die_offset != NULL)
  258.     *die_offset = type->ty_cu_offset + 
  259.         type->ty_context->tp_info_offset;
  260.  
  261.     if (cu_offset != NULL)
  262.     *cu_offset = type->ty_context->tp_info_offset;
  263.  
  264.     *returned_name = (type->ty_name);
  265.     return DW_DLV_OK;
  266. }
  267.