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

  1. /*
  2.     dwarf_alloc.c
  3.     $Revision: 1.21 $   $Date: 1994/06/17 02:39:01 $
  4. */
  5.  
  6. #include <sys/types.h>
  7. #include <malloc.h>
  8.  
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include "dwarf_incl.h"
  12. #include "bstring.h"
  13.  
  14. /*
  15.     These files are included to get the sizes
  16.     of structs to set the ah_alloc_size field
  17.     of the Dwarf_Alloc_Hdr_s structs for each
  18.     allocation type.
  19. */
  20. #include "dwarf_line.h"
  21. #include "dwarf_global.h"
  22. #include "dwarf_arange.h"
  23. #include "dwarf_abbrev.h"
  24. #include "dwarf_die_deliv.h"
  25. #include "dwarf_frame.h"
  26. #include "dwarf_loc.h"
  27. #include "dwarf_funcs.h"
  28. #include "dwarf_types.h"
  29. #include "dwarf_vars.h"
  30. #include "dwarf_weaks.h"
  31.  
  32.  
  33. /*
  34.     This function is given a pointer to the header
  35.     structure that is used to allocate 1 struct of
  36.     the type given by alloc_type.  It first checks
  37.     if a struct is available in its free list.  If
  38.     not, it checks if 1 is available in its blob, 
  39.     which is a chunk of memory that is reserved for
  40.     its use.  If not, it malloc's a chunk.  The
  41.     initial part of it is used to store the end
  42.     address of the chuck, and also to keep track 
  43.     of the number of free structs in that chunk.
  44.     This information is used for freeing the chunk
  45.     when all the structs in it are free.
  46.  
  47.     Assume all input arguments have been validated.
  48.  
  49.     This function can be used only to allocate 1
  50.     struct of the given type.
  51.  
  52.     It returns a pointer to the struct that the
  53.     user can use.  It returns NULL only when it
  54.     is out of free structs, and cannot malloc 
  55.     any more.  The struct returned is zero-ed.
  56.  
  57.     A pointer to the chunk that the struct belongs
  58.     to is stored in the bytes preceding the
  59.     returned address.  Since this pointer it
  60.     never overwritten, when a struct is allocated
  61.     from the free_list this pointer does not
  62.     have to be written.  In the 2 other cases,
  63.     where the struct is allocated from a new
  64.     chunk, or the blob, a pointer to the chunk
  65.     is written.
  66. */
  67. Dwarf_Ptr 
  68. _dwarf_find_memory (
  69.     Dwarf_Alloc_Hdr    alloc_hdr,
  70.     Dwarf_Small        alloc_type
  71. )
  72. {
  73.     /* Pointer to the struct allocated. */
  74.     Dwarf_Small        *ret_mem;
  75.  
  76.     /* Pointer to info about chunks allocated. */
  77.     Dwarf_Alloc_Area    alloc_area;
  78.  
  79.     /* Size of chunk malloc'ed when no free structs left. */
  80.     Dwarf_Signed    mem_block_size;
  81.  
  82.     /* Pointer to block malloc'ed. */
  83.     Dwarf_Small        *mem_block;
  84.  
  85.     /* ***** BEGIN CODE ***** */
  86.  
  87.     /* 
  88.         If every struct in the chunks malloc'ed is busy, go
  89.         directly to mallocing a new chunk.  Otherwise, check
  90.         the alloc_area from which the last allocation was
  91.         made.  If that is not succesful, then search the list
  92.         of alloc_area's from alloc_header.
  93.     */
  94.     if (alloc_hdr->ah_struct_alloc_count > 0 &&
  95.     alloc_hdr->ah_struct_alloc_count % alloc_hdr->ah_alloc_num == 0) 
  96.     alloc_area = NULL;
  97.     else {
  98.         alloc_area = alloc_hdr->ah_last_alloc_area;
  99.         if (alloc_area == NULL || alloc_area->aa_free_count == 0)
  100.             for (alloc_area = alloc_hdr->ah_alloc_area_head;
  101.             alloc_area != NULL && alloc_area->aa_free_count == 0;
  102.             alloc_area = alloc_area->aa_next);
  103.     }
  104.  
  105.     if (alloc_area != NULL) {
  106.         alloc_area->aa_free_count--;
  107.  
  108.         if (alloc_area->aa_free_list != NULL) {
  109.         ret_mem = alloc_area->aa_free_list;
  110.  
  111.             /* 
  112.             Update the free list.  The initial part of the struct
  113.                 is used to hold a pointer to the next struct on the free
  114.                 list.  In this way, the free list chain is maintained at
  115.                 0 memory cost.
  116.             */
  117.         alloc_area->aa_free_list = 
  118.             ((Dwarf_Free_List)alloc_area->aa_free_list)->fl_next;
  119.         }
  120.  
  121.         else if (alloc_area->aa_blob_start < alloc_area->aa_blob_end) {
  122.         ret_mem = alloc_area->aa_blob_start;
  123.  
  124.         /* 
  125.             Store pointer to chunk this struct belongs to in the 
  126.             first few bytes.  Return pointer to bytes after this
  127.             pointer storage.
  128.         */
  129.         *(Dwarf_Alloc_Area *)ret_mem = alloc_area;
  130.         ret_mem += sizeof(void *);
  131.  
  132.         alloc_area->aa_blob_start += alloc_hdr->ah_alloc_size;
  133.         }
  134.     }
  135.  
  136.     /* New memory has to malloc'ed since there are no free structs. */
  137.     else {
  138.  
  139.         /* 
  140.         Increment count of chunks currently malloc'ed
  141.             for this allocation type, and update the maximum
  142.             count if is smaller than the current count.
  143.         */
  144.     alloc_hdr->ah_curr_alloc++;
  145.     if (alloc_hdr->ah_curr_alloc > alloc_hdr->ah_max_alloc)
  146.         alloc_hdr->ah_max_alloc = alloc_hdr->ah_curr_alloc;
  147.  
  148.         /* 
  149.         Allocate memory to contain the required number 
  150.         of structs and the Dwarf_Alloc_Area_s to control
  151.         it.
  152.         */
  153.     mem_block_size = alloc_hdr->ah_malloc_length + 
  154.         sizeof(struct Dwarf_Alloc_Area_s);
  155.  
  156.     mem_block = malloc(mem_block_size);
  157.     if (mem_block == NULL) {
  158.         return(NULL);
  159.     }
  160.  
  161.         /* 
  162.         Zero out the Dwarf_Alloc_Area_s part of the
  163.             chunk.  The rest is zero-ed out as each struct
  164.             is returned to the user.
  165.         */
  166.         bzero(mem_block, sizeof(struct Dwarf_Alloc_Area_s));
  167.  
  168.         /*
  169.         Attach the Dwarf_Alloc_Area_s struct to
  170.         the list of chunks malloc'ed for this
  171.         struct type.
  172.         */
  173.     alloc_area = (Dwarf_Alloc_Area)mem_block;
  174.     if (alloc_hdr->ah_alloc_area_head != NULL)
  175.         alloc_hdr->ah_alloc_area_head->aa_prev = alloc_area;
  176.     alloc_area->aa_next = alloc_hdr->ah_alloc_area_head;
  177.     alloc_hdr->ah_alloc_area_head = alloc_area;
  178.  
  179.     alloc_area->aa_alloc_hdr = alloc_hdr;
  180.     alloc_area->aa_free_count = alloc_hdr->ah_alloc_num - 1;
  181.  
  182.         /* 
  183.         The struct returned begins immediately after
  184.             the Dwarf_Alloc_Area_s struct.
  185.         */
  186.     ret_mem = mem_block + sizeof(struct Dwarf_Alloc_Area_s);
  187.     alloc_area->aa_blob_start = ret_mem + alloc_hdr->ah_alloc_size;
  188.     alloc_area->aa_blob_end = mem_block + mem_block_size;
  189.  
  190.         /* 
  191.             Store pointer to chunk this struct belongs to in the 
  192.             first few bytes.  Return pointer to bytes after this
  193.             pointer storage.
  194.         */
  195.     *(Dwarf_Alloc_Area *)ret_mem = alloc_area;
  196.         ret_mem += sizeof(void *);
  197.     }
  198.  
  199.     alloc_hdr->ah_last_alloc_area = alloc_area;
  200.     alloc_hdr->ah_struct_alloc_count++;
  201.     bzero(ret_mem, alloc_hdr->ah_alloc_size - sizeof(void *));
  202.     return(ret_mem);
  203. }
  204.  
  205.  
  206. /*
  207.     This function returns a pointer to a region
  208.     of memory.  For alloc_types that are not
  209.     strings or lists of pointers, only 1 struct
  210.     can be requested at a time.  This is indicated
  211.     by an input count of 1.  For strings, count 
  212.     equals the length of the string it will
  213.     contain, i.e it is the length of the string
  214.     plus 1 for the terminating null.  For lists
  215.     of pointers, count is equal to the number of
  216.     pointers.  For DW_DLA_FRAME_BLOCK, and
  217.     DW_DLA_LOC_BLOCK allocation types also, count
  218.     is the count of the number of structs needed.
  219.  
  220.     This function cannot be used to allocate a 
  221.     Dwarf_Debug_s struct.
  222. */
  223. Dwarf_Ptr 
  224. _dwarf_get_alloc (
  225.     Dwarf_Debug     dbg,
  226.     Dwarf_Small        alloc_type,
  227.     Dwarf_Unsigned     count
  228. )
  229. {
  230.     Dwarf_Alloc_Hdr    alloc_hdr;
  231.  
  232.     Dwarf_Ptr        ret_mem;
  233.  
  234.     Dwarf_Signed    size = 0;
  235.  
  236.     if (dbg == NULL || dbg->de_alloc_hdr == NULL) 
  237.     return(NULL);
  238.  
  239.     if (alloc_type == DW_DLA_STRING)  {
  240.     size = count;
  241.     }else if (alloc_type == DW_DLA_LIST) {
  242.     size = count * sizeof(Dwarf_Ptr);
  243.     }else if (alloc_type == DW_DLA_FRAME_BLOCK) {
  244.     size = count * sizeof(Dwarf_Frame_Op);
  245.  
  246.     }else if (alloc_type == DW_DLA_LOC_BLOCK) {
  247.     size = count * sizeof(Dwarf_Loc);
  248.     }else if (alloc_type == DW_DLA_ADDR) {
  249.     /* need space for either Dwarf_Off or Dwarf_Addr array */
  250.     int lsize = sizeof(Dwarf_Addr);
  251.     if(sizeof(Dwarf_Off) > lsize) {
  252.         lsize = sizeof(Dwarf_Off);
  253.     }
  254.     size = count * lsize;
  255.     } else if (alloc_type == DW_DLA_HASH_TABLE){
  256.     size = ABBREV_HASH_TABLE_SIZE * 2 * sizeof(Dwarf_Abbrev_List);
  257.  
  258.     } else if (alloc_type > DW_DLA_STRING && alloc_type <= MAX_DW_DLA) {
  259.     alloc_hdr = dbg->de_alloc_hdr[alloc_type];
  260.     if (alloc_hdr != NULL)
  261.         return(_dwarf_find_memory(alloc_hdr, alloc_type));
  262.     
  263.     /*  
  264.         This is for situations where there is a Dwarf Error
  265.         even before _dwarf_setup_debug() has executed, namely 
  266.         in _dwarf_setup().  The reason _dwarf_setup_debug() 
  267.         has to execute after _dwarf_setup() is to take advantage 
  268.         of the size information that _dwarf_setup() can provide.  
  269.         In this case, a Dwarf_Error_s struct is simply malloc'ed.  
  270.         This memory will most probably leak.
  271.     */
  272.     if (alloc_type == DW_DLA_ERROR)
  273.         size = sizeof(struct Dwarf_Error_s);
  274.     else
  275.         return(NULL);
  276.     }
  277.  
  278.     ret_mem = malloc(size);
  279.     if (ret_mem != NULL) bzero(ret_mem, size);
  280.     return(ret_mem);
  281. }
  282.  
  283.  
  284. /*
  285.     This function is used to deallocate a region of memory
  286.     that was obtained by a call to _dwarf_get_alloc.  Note
  287.     that though dwarf_dealloc() is a public function, 
  288.     _dwarf_get_alloc() isn't.  
  289.  
  290.     For lists, typically arrays of pointers, it is assumed
  291.     that the space was allocated by a direct call to malloc,
  292.     and so a straight free() is done.  This is also the case
  293.     for variable length blocks such as DW_DLA_FRAME_BLOCK
  294.     and DW_DLA_LOC_BLOCK.
  295.  
  296.     For strings, the pointer might point to a string in 
  297.     .debug_info or .debug_string.  After this is checked,
  298.     and if found not to be the case, a free() is done,
  299.     again on the assumption that a malloc was used to
  300.     obtain the space.
  301.  
  302.     For other types of structs, a pointer to the chunk that
  303.     the struct was allocated out of, is present in the bytes
  304.     preceding the pointer passed in.  For this chunk it is 
  305.     checked whether all the structs in that chunk are now free.  
  306.     If so, the entire chunk is free_ed.  Otherwise, the space 
  307.     is added to the free list for that chunk, and the free count
  308.     incremented.
  309.  
  310.     This function does not return anything.
  311. */
  312. void
  313. dwarf_dealloc (
  314.     Dwarf_Debug        dbg,
  315.     Dwarf_Ptr        space,
  316.     Dwarf_Unsigned    alloc_type
  317. )
  318. {
  319.     Dwarf_Alloc_Hdr    alloc_hdr;
  320.     Dwarf_Alloc_Area    alloc_area;
  321.  
  322.     if (dbg == NULL || dbg->de_alloc_hdr == NULL || space == NULL) {
  323.     return;
  324.     }
  325.  
  326.     /* 
  327.         A string pointer may point into .debug_info or 
  328.         .debug_string.  Otherwise, they are directly malloc'ed.
  329.     */
  330.     if (alloc_type == DW_DLA_STRING) {
  331.     if ((Dwarf_Small *)space >= dbg->de_debug_info &&
  332.         (Dwarf_Small *)space < dbg->de_debug_info + dbg->de_debug_info_size)
  333.         return;
  334.  
  335.     if ((Dwarf_Small *)space >= dbg->de_debug_line &&
  336.         (Dwarf_Small *)space < dbg->de_debug_line + dbg->de_debug_line_size)
  337.         return;
  338.  
  339.     if ((Dwarf_Small *)space >= dbg->de_debug_pubnames &&
  340.         (Dwarf_Small *)space < 
  341.         dbg->de_debug_pubnames + dbg->de_debug_pubnames_size)
  342.         return;
  343.  
  344.     if ((Dwarf_Small *)space >= dbg->de_debug_frame &&
  345.         (Dwarf_Small *)space < 
  346.         dbg->de_debug_frame + dbg->de_debug_frame_size)
  347.         return;
  348.  
  349.     if ((Dwarf_Small *)space >= dbg->de_debug_str &&
  350.         (Dwarf_Small *)space < dbg->de_debug_str + dbg->de_debug_str_size)
  351.         return;
  352.  
  353.     if ((Dwarf_Small *)space >= dbg->de_debug_funcnames &&
  354.         (Dwarf_Small *)space < 
  355.         dbg->de_debug_funcnames + dbg->de_debug_funcnames_size)
  356.         return;
  357.  
  358.     if ((Dwarf_Small *)space >= dbg->de_debug_typenames &&
  359.         (Dwarf_Small *)space < 
  360.         dbg->de_debug_typenames + dbg->de_debug_typenames_size)
  361.         return;
  362.  
  363.     if ((Dwarf_Small *)space >= dbg->de_debug_varnames &&
  364.         (Dwarf_Small *)space < 
  365.         dbg->de_debug_varnames + dbg->de_debug_varnames_size)
  366.         return;
  367.  
  368.     if ((Dwarf_Small *)space >= dbg->de_debug_weaknames &&
  369.         (Dwarf_Small *)space < 
  370.         dbg->de_debug_weaknames + dbg->de_debug_weaknames_size)
  371.         return;
  372.  
  373.     free(space); 
  374.     return;
  375.     }
  376.  
  377.     if (alloc_type == DW_DLA_LIST || alloc_type == DW_DLA_FRAME_BLOCK ||
  378.     alloc_type == DW_DLA_LOC_BLOCK || alloc_type == DW_DLA_HASH_TABLE
  379.     || alloc_type == DW_DLA_ADDR
  380.                                   ) {
  381.     free(space); 
  382.     return;
  383.     }
  384.  
  385.  
  386.     if (alloc_type < DW_DLA_STRING || alloc_type > MAX_DW_DLA) {
  387.     return;
  388.     }
  389.  
  390.     /* Ah_alloc_num equal 1 indicates an unused alloc type. */
  391.     alloc_hdr = dbg->de_alloc_hdr[alloc_type];
  392.     if (alloc_hdr->ah_alloc_num == 1) {
  393.     return;
  394.     }
  395.  
  396.     /* Get pointer to Dwarf_Alloc_Area this struct came from. */
  397.     alloc_area = *(Dwarf_Alloc_Area *)((char *)space - sizeof(void *));
  398. #if 0
  399.     if(alloc_area == 0) {
  400.     /* ERROR!  This should not be null!
  401.        We can either abort, or let it coredump below.
  402.        Or return, pretending all is well.
  403.        We go on, letting program crash. Is caller error.
  404.     */
  405.     }
  406. #endif
  407.  
  408.     /* 
  409.         Check that the alloc_hdr field of the alloc_area we have
  410.         is pointing to the right alloc_hdr.  This is used to catch
  411.         use of incorrect deallocation code by the user.
  412.     */
  413.     if (alloc_area->aa_alloc_hdr != alloc_hdr)
  414.     return;
  415.  
  416.     alloc_hdr->ah_struct_alloc_count--;
  417.     alloc_area->aa_free_count++;
  418.  
  419.     /*
  420.         Give chunk back to malloc only when every struct is
  421.         free'd, and there is more than one chunk malloc'ed
  422.         for the type.
  423.     */
  424.     if (alloc_area->aa_free_count == alloc_hdr->ah_alloc_num &&
  425.     alloc_hdr->ah_struct_alloc_count > 0) {
  426.  
  427.     if (alloc_area->aa_prev != NULL)
  428.         alloc_area->aa_prev->aa_next = alloc_area->aa_next;
  429.     else 
  430.         alloc_hdr->ah_alloc_area_head = alloc_area->aa_next;
  431.  
  432.     if (alloc_area->aa_next != NULL)
  433.         alloc_area->aa_next->aa_prev = alloc_area->aa_prev;
  434.  
  435.     alloc_hdr->ah_curr_alloc--;
  436.  
  437.     if (alloc_area == alloc_hdr->ah_last_alloc_area)
  438.         alloc_hdr->ah_last_alloc_area = NULL;
  439.     free(alloc_area); 
  440.     }
  441.  
  442.     else {
  443.     ((Dwarf_Free_List)space)->fl_next = alloc_area->aa_free_list;
  444.     alloc_area->aa_free_list = space;
  445.     }
  446. }
  447.  
  448.  
  449. /*
  450.     Allocates space for a Dwarf_Debug_s struct,
  451.     since one does not exist.
  452. */
  453. Dwarf_Debug
  454. _dwarf_get_debug (
  455.     void
  456. )
  457. {
  458.     Dwarf_Debug        dbg;
  459.  
  460.     dbg = (Dwarf_Debug)malloc(sizeof(struct Dwarf_Debug_s));
  461.     if (dbg == NULL) return(NULL);
  462.     else bzero(dbg, sizeof(struct Dwarf_Debug_s));
  463.  
  464.     return(dbg);
  465. }
  466.  
  467.  
  468. /*
  469.     Sets up the Dwarf_Debug_s struct for all the
  470.     allocation types currently defined.  
  471.     Allocation types DW_DLA_STRING, DW_DLA_LIST,
  472.     DW_DLA_FRAME_BLOCK, DW_DLA_LOC_BLOCK are 
  473.     malloc'ed directly.
  474.  
  475.     This routine should be called after _dwarf_setup(),
  476.     so that information about the sizes of the Dwarf
  477.     sections can be used to decide the number of
  478.     structs of each type malloc'ed.
  479.  
  480.     Also DW_DLA_ELLIST, DW_DLA_BOUNDS, DW_DLA_TYPE,
  481.     DW_DLA_SUBSCR, DW_DLA_LINEBUF allocation types
  482.     are currently not used.  Also, DW_DLA_DEBUG
  483.     structs cannot be deallocated using this routine.
  484.     The ah_alloc_size and ah_alloc_num fields for
  485.     these types have been set to 1 for efficiency
  486.     in dwarf_get_alloc().
  487.  
  488.     Ah_alloc_num should be greater than 1 for all
  489.     types that are currently being used.
  490.  
  491.     Therefore, for these allocation types the
  492.     ah_alloc_size, and ah_alloc_num fields do not
  493.     need to be initialized.
  494.  
  495.     Being an internal routine, assume proper dbg.
  496. */
  497. Dwarf_Debug
  498. _dwarf_setup_debug (
  499.     Dwarf_Debug        dbg
  500. )
  501. {
  502.     Dwarf_Alloc_Hdr    alloc_hdr;
  503.  
  504.     Dwarf_Shalf        i;
  505.  
  506.     for (i = 1; i <= MAX_DW_DLA; i++) {
  507.  
  508.     alloc_hdr = (Dwarf_Alloc_Hdr)malloc(sizeof(struct Dwarf_Alloc_Hdr_s));
  509.     if (alloc_hdr == NULL) return(NULL);
  510.     else bzero(alloc_hdr, sizeof(struct Dwarf_Alloc_Hdr_s));
  511.  
  512.     dbg->de_alloc_hdr[i] = alloc_hdr;
  513.  
  514.     switch (i) {
  515.         case DW_DLA_STRING :
  516.         /* not actually used */
  517.         alloc_hdr->ah_alloc_size = 1;
  518.         alloc_hdr->ah_alloc_num = 1;
  519.         alloc_hdr->ah_malloc_length = 1;
  520.         break;
  521.  
  522.         case DW_DLA_LOC :
  523.         alloc_hdr->ah_alloc_size = ROUND_SIZE_WITH_POINTER(Dwarf_Loc);
  524.         alloc_hdr->ah_alloc_num = 64;
  525.         alloc_hdr->ah_malloc_length = 
  526.             64 * ROUND_SIZE_WITH_POINTER(Dwarf_Loc);
  527.         break;
  528.  
  529.         case DW_DLA_LOCDESC :
  530.         alloc_hdr->ah_alloc_size = 
  531.             ROUND_SIZE_WITH_POINTER(Dwarf_Locdesc);
  532.         alloc_hdr->ah_alloc_num = 64;
  533.         alloc_hdr->ah_malloc_length = 
  534.             64 * ROUND_SIZE_WITH_POINTER(Dwarf_Locdesc);
  535.         break;
  536.  
  537.         case DW_DLA_ELLIST :
  538.         alloc_hdr->ah_alloc_size = 1;
  539.         alloc_hdr->ah_alloc_num = 1;
  540.         alloc_hdr->ah_malloc_length = 1;
  541.         break;
  542.  
  543.         case DW_DLA_BOUNDS :
  544.         alloc_hdr->ah_alloc_size = 1;
  545.         alloc_hdr->ah_alloc_num = 1;
  546.         alloc_hdr->ah_malloc_length = 1;
  547.         break;
  548.  
  549.         case DW_DLA_BLOCK :
  550.         alloc_hdr->ah_alloc_size = 
  551.             ROUND_SIZE_WITH_POINTER(Dwarf_Block);
  552.         alloc_hdr->ah_alloc_num = 64;
  553.         alloc_hdr->ah_malloc_length = 
  554.             64 * ROUND_SIZE_WITH_POINTER(Dwarf_Block);
  555.         break;
  556.         
  557.         case DW_DLA_DEBUG :
  558.         alloc_hdr->ah_alloc_size = 1;
  559.         alloc_hdr->ah_alloc_num = 1;
  560.         alloc_hdr->ah_malloc_length = 1;
  561.         break;
  562.  
  563.         case DW_DLA_DIE :
  564.         alloc_hdr->ah_alloc_size = 
  565.             ROUND_SIZE_WITH_POINTER(struct Dwarf_Die_s);
  566.         alloc_hdr->ah_alloc_num = 128;
  567.         alloc_hdr->ah_malloc_length = 
  568.             128 * ROUND_SIZE_WITH_POINTER(struct Dwarf_Die_s);
  569.         break;
  570.  
  571.         case DW_DLA_LINE :
  572.         alloc_hdr->ah_alloc_size = 
  573.             ROUND_SIZE_WITH_POINTER(struct Dwarf_Line_s);
  574.         alloc_hdr->ah_alloc_num = 128;
  575.         alloc_hdr->ah_malloc_length = 
  576.             128 * ROUND_SIZE_WITH_POINTER(struct Dwarf_Line_s);
  577.         break;
  578.  
  579.         case DW_DLA_ATTR :
  580.         alloc_hdr->ah_alloc_size = 
  581.             ROUND_SIZE_WITH_POINTER(struct Dwarf_Attribute_s);
  582.         alloc_hdr->ah_alloc_num = 256;
  583.         alloc_hdr->ah_malloc_length = 
  584.             256 * ROUND_SIZE_WITH_POINTER(struct Dwarf_Attribute_s);
  585.         break;
  586.  
  587.         case DW_DLA_TYPE :
  588.         alloc_hdr->ah_alloc_size = 1;
  589.         alloc_hdr->ah_alloc_num = 1;
  590.         alloc_hdr->ah_malloc_length = 1;
  591.         break;
  592.  
  593.         case DW_DLA_SUBSCR :
  594.         alloc_hdr->ah_alloc_size = 1;
  595.         alloc_hdr->ah_alloc_num = 1;
  596.         alloc_hdr->ah_malloc_length = 1;
  597.         break;
  598.  
  599.         case DW_DLA_GLOBAL :
  600.         alloc_hdr->ah_alloc_size = 
  601.             ROUND_SIZE_WITH_POINTER(struct Dwarf_Global_s);
  602.         alloc_hdr->ah_alloc_num = 128;
  603.         alloc_hdr->ah_malloc_length = 
  604.             128 * ROUND_SIZE_WITH_POINTER(struct Dwarf_Global_s);
  605.         break;
  606.  
  607.         case DW_DLA_ERROR :
  608.         alloc_hdr->ah_alloc_size = 
  609.             ROUND_SIZE_WITH_POINTER(struct Dwarf_Error_s);
  610.         alloc_hdr->ah_alloc_num = 64;
  611.         alloc_hdr->ah_malloc_length = 
  612.             64 * ROUND_SIZE_WITH_POINTER(struct Dwarf_Error_s);
  613.         break;
  614.  
  615.         case DW_DLA_LIST :
  616.         /* not actually used */
  617.         alloc_hdr->ah_alloc_size = 1;
  618.         alloc_hdr->ah_alloc_num = 1;
  619.         alloc_hdr->ah_malloc_length = 1;
  620.         break;
  621.  
  622.         case DW_DLA_LINEBUF :
  623.         alloc_hdr->ah_alloc_size = 1;
  624.         alloc_hdr->ah_alloc_num = 1;
  625.         alloc_hdr->ah_malloc_length = 1;
  626.         break;
  627.  
  628.         case DW_DLA_ARANGE :
  629.         alloc_hdr->ah_alloc_size = 
  630.             ROUND_SIZE_WITH_POINTER(struct Dwarf_Arange_s);
  631.         alloc_hdr->ah_alloc_num = 64;
  632.         alloc_hdr->ah_malloc_length = 
  633.             64 * ROUND_SIZE_WITH_POINTER(struct Dwarf_Arange_s);
  634.         break;
  635.  
  636.         case DW_DLA_ABBREV :
  637.         alloc_hdr->ah_alloc_size = 
  638.             ROUND_SIZE_WITH_POINTER(struct Dwarf_Abbrev_s);
  639.         alloc_hdr->ah_alloc_num = 128;
  640.         alloc_hdr->ah_malloc_length = 
  641.             128 * ROUND_SIZE_WITH_POINTER(struct Dwarf_Abbrev_s);
  642.         break;
  643.  
  644.         case DW_DLA_ABBREV_LIST :
  645.         alloc_hdr->ah_alloc_size = 
  646.             ROUND_SIZE_WITH_POINTER(struct Dwarf_Abbrev_List_s);
  647.         alloc_hdr->ah_alloc_num = 128;
  648.         alloc_hdr->ah_malloc_length = 128 * 
  649.             ROUND_SIZE_WITH_POINTER(struct Dwarf_Abbrev_List_s);
  650.         break;
  651.  
  652.         case DW_DLA_CHAIN :
  653.         alloc_hdr->ah_alloc_size = 
  654.             ROUND_SIZE_WITH_POINTER(struct Dwarf_Chain_s);
  655.         alloc_hdr->ah_alloc_num = 128;
  656.         alloc_hdr->ah_malloc_length = 
  657.             128 * ROUND_SIZE_WITH_POINTER(struct Dwarf_Chain_s);
  658.         break;
  659.         
  660.         case DW_DLA_CU_CONTEXT :
  661.         alloc_hdr->ah_alloc_size = 
  662.             ROUND_SIZE_WITH_POINTER(struct Dwarf_CU_Context_s);
  663.         alloc_hdr->ah_alloc_num = 64;
  664.         alloc_hdr->ah_malloc_length = 
  665.             64 * ROUND_SIZE_WITH_POINTER(struct Dwarf_CU_Context_s);
  666.         break;
  667.  
  668.         case DW_DLA_FRAME :
  669.         alloc_hdr->ah_alloc_size = 
  670.             ROUND_SIZE_WITH_POINTER(struct Dwarf_Frame_s);
  671.         alloc_hdr->ah_alloc_num = 64;
  672.         alloc_hdr->ah_malloc_length = 
  673.             64 * ROUND_SIZE_WITH_POINTER(struct Dwarf_Frame_s);
  674.         break;
  675.  
  676.         case DW_DLA_FRAME_OP :
  677.         alloc_hdr->ah_alloc_size = 
  678.             ROUND_SIZE_WITH_POINTER(Dwarf_Frame_Op);
  679.         alloc_hdr->ah_alloc_num = 128;
  680.         alloc_hdr->ah_malloc_length = 
  681.             128 * ROUND_SIZE_WITH_POINTER(Dwarf_Frame_Op);
  682.         break;
  683.  
  684.         case DW_DLA_CIE :
  685.         alloc_hdr->ah_alloc_size = 
  686.             ROUND_SIZE_WITH_POINTER(struct Dwarf_Cie_s);
  687.         alloc_hdr->ah_alloc_num = 64;
  688.         alloc_hdr->ah_malloc_length = 
  689.             64 * ROUND_SIZE_WITH_POINTER(struct Dwarf_Cie_s);
  690.         break;
  691.     
  692.         case DW_DLA_FDE :
  693.         alloc_hdr->ah_alloc_size = 
  694.             ROUND_SIZE_WITH_POINTER(struct Dwarf_Fde_s);
  695.         alloc_hdr->ah_alloc_num = 64;
  696.         alloc_hdr->ah_malloc_length = 
  697.             64 * ROUND_SIZE_WITH_POINTER(struct Dwarf_Fde_s);
  698.         break;
  699.     
  700.         case DW_DLA_GLOBAL_CONTEXT :
  701.         alloc_hdr->ah_alloc_size = 
  702.             ROUND_SIZE_WITH_POINTER(struct Dwarf_Global_Context_s);
  703.         alloc_hdr->ah_alloc_num = 64;
  704.         alloc_hdr->ah_malloc_length = 64 * 
  705.             ROUND_SIZE_WITH_POINTER(struct Dwarf_Global_Context_s);
  706.         break;
  707.  
  708.         case DW_DLA_FILE_ENTRY :
  709.         alloc_hdr->ah_alloc_size = 
  710.             ROUND_SIZE_WITH_POINTER(struct Dwarf_File_Entry_s);
  711.         alloc_hdr->ah_alloc_num = 64;
  712.         alloc_hdr->ah_malloc_length = 
  713.             64 * ROUND_SIZE_WITH_POINTER(struct Dwarf_File_Entry_s);
  714.         break;
  715.  
  716.         case DW_DLA_LINE_CONTEXT :
  717.         alloc_hdr->ah_alloc_size = 
  718.             ROUND_SIZE_WITH_POINTER(struct Dwarf_Line_Context_s);
  719.         alloc_hdr->ah_alloc_num = 64;
  720.         alloc_hdr->ah_malloc_length = 
  721.             64 * ROUND_SIZE_WITH_POINTER(struct Dwarf_Line_Context_s);
  722.         break;
  723.  
  724.         case DW_DLA_LOC_CHAIN :
  725.         alloc_hdr->ah_alloc_size = 
  726.             ROUND_SIZE_WITH_POINTER(struct Dwarf_Loc_Chain_s);
  727.         alloc_hdr->ah_alloc_num = 64;
  728.         alloc_hdr->ah_malloc_length = 
  729.             64 * ROUND_SIZE_WITH_POINTER(struct Dwarf_Loc_Chain_s);
  730.         break;
  731.  
  732.         case DW_DLA_LOC_BLOCK :
  733.         /* not actually used */
  734.         alloc_hdr->ah_alloc_size = 1;
  735.         alloc_hdr->ah_alloc_num = 1;
  736.         alloc_hdr->ah_malloc_length = 1;
  737.         break;
  738.  
  739.         case DW_DLA_FRAME_BLOCK :
  740.         /* not actually used */
  741.         alloc_hdr->ah_alloc_size = 1;
  742.         alloc_hdr->ah_alloc_num = 1;
  743.         alloc_hdr->ah_malloc_length = 1;
  744.         break;
  745.  
  746.         case DW_DLA_HASH_TABLE :
  747.         /* not actually used */
  748.         alloc_hdr->ah_alloc_size = 1;
  749.         alloc_hdr->ah_alloc_num = 1;
  750.         alloc_hdr->ah_malloc_length = 1;
  751.         break;
  752.  
  753.         case DW_DLA_FUNC :
  754.         alloc_hdr->ah_alloc_size = 
  755.             ROUND_SIZE_WITH_POINTER(struct Dwarf_Func_s);
  756.         alloc_hdr->ah_alloc_num = 128;
  757.         alloc_hdr->ah_malloc_length = 
  758.             128 * ROUND_SIZE_WITH_POINTER(struct Dwarf_Func_s);
  759.         break;
  760.  
  761.         case DW_DLA_FUNC_CONTEXT :
  762.         alloc_hdr->ah_alloc_size = 
  763.             ROUND_SIZE_WITH_POINTER(struct Dwarf_Func_Context_s);
  764.         alloc_hdr->ah_alloc_num = 64;
  765.         alloc_hdr->ah_malloc_length = 
  766.             64 * ROUND_SIZE_WITH_POINTER(struct Dwarf_Func_Context_s);
  767.         break;
  768.  
  769.         case DW_DLA_TYPENAME :
  770.         alloc_hdr->ah_alloc_size = 
  771.             ROUND_SIZE_WITH_POINTER(struct Dwarf_Type_s);
  772.         alloc_hdr->ah_alloc_num = 128;
  773.         alloc_hdr->ah_malloc_length = 
  774.             128 * ROUND_SIZE_WITH_POINTER(struct Dwarf_Type_s);
  775.         break;
  776.  
  777.         case DW_DLA_TYPENAME_CONTEXT :
  778.         alloc_hdr->ah_alloc_size = 
  779.             ROUND_SIZE_WITH_POINTER(struct Dwarf_Type_Context_s);
  780.         alloc_hdr->ah_alloc_num = 64;
  781.         alloc_hdr->ah_malloc_length = 
  782.             64 * ROUND_SIZE_WITH_POINTER(struct Dwarf_Type_Context_s);
  783.         break;
  784.  
  785.         case DW_DLA_VAR :
  786.         alloc_hdr->ah_alloc_size = 
  787.             ROUND_SIZE_WITH_POINTER(struct Dwarf_Var_s);
  788.         alloc_hdr->ah_alloc_num = 128;
  789.         alloc_hdr->ah_malloc_length = 
  790.             128 * ROUND_SIZE_WITH_POINTER(struct Dwarf_Var_s);
  791.         break;
  792.  
  793.         case DW_DLA_VAR_CONTEXT :
  794.         alloc_hdr->ah_alloc_size = 
  795.             ROUND_SIZE_WITH_POINTER(struct Dwarf_Var_Context_s);
  796.         alloc_hdr->ah_alloc_num = 64;
  797.         alloc_hdr->ah_malloc_length = 
  798.             64 * ROUND_SIZE_WITH_POINTER(struct Dwarf_Var_Context_s);
  799.         break;
  800.  
  801.         case DW_DLA_WEAK :
  802.         alloc_hdr->ah_alloc_size = 
  803.             ROUND_SIZE_WITH_POINTER(struct Dwarf_Weak_s);
  804.         alloc_hdr->ah_alloc_num = 128;
  805.         alloc_hdr->ah_malloc_length = 
  806.             128 * ROUND_SIZE_WITH_POINTER(struct Dwarf_Weak_s);
  807.         break;
  808.  
  809.         case DW_DLA_ADDR :
  810.         /* not actually used */
  811.         alloc_hdr->ah_alloc_size = 1; 
  812.         alloc_hdr->ah_alloc_num = 1;
  813.         alloc_hdr->ah_malloc_length =  1;
  814.         break;
  815.  
  816.         case DW_DLA_WEAK_CONTEXT :
  817.         alloc_hdr->ah_alloc_size = 
  818.             ROUND_SIZE_WITH_POINTER(struct Dwarf_Weak_Context_s);
  819.         alloc_hdr->ah_alloc_num = 64;
  820.         alloc_hdr->ah_malloc_length = 
  821.             64 * ROUND_SIZE_WITH_POINTER(struct Dwarf_Weak_Context_s);
  822.         break;
  823.     }
  824.  
  825.     }
  826.     return(dbg);
  827. }
  828.  
  829.  
  830. /*
  831.     This function prints out the statistics
  832.     collected on allocation of memory chunks.
  833. */
  834. void 
  835. dwarf_print_memory_stats (
  836.     Dwarf_Debug     dbg
  837. )
  838. {
  839.     Dwarf_Alloc_Hdr    alloc_hdr;
  840.     Dwarf_Shalf        i;
  841.  
  842.         /* 
  843.         Alloc types start at 1, not 0.   
  844.         Hence, the first NULL string, and 
  845.         also a size of MAX_DW_DLA + 1.
  846.     */
  847.     char        *alloc_type_name [MAX_DW_DLA + 1] = {
  848.                 "",    
  849.                 "DW_DLA_STRING",
  850.                 "DW_DLA_LOC",
  851.                 "DW_DLA_LOCDESC",
  852.                 "DW_DLA_ELLIST",
  853.                 "DW_DLA_BOUNDS",
  854.                 "DW_DLA_BLOCK",
  855.                 "DW_DLA_DEBUG",
  856.                 "DW_DLA_DIE",
  857.                 "DW_DLA_LINE",
  858.                 "DW_DLA_ATTR",
  859.                 "DW_DLA_TYPE",
  860.                 "DW_DLA_SUBSCR",
  861.                 "DW_DLA_GLOBAL",
  862.                 "DW_DLA_ERROR",
  863.                 "DW_DLA_LIST",
  864.                 "DW_DLA_LINEBUF",
  865.                 "DW_DLA_ARANGE",
  866.                 "DW_DLA_ABBREV",
  867.                 "DW_DLA_FRAME_OP",
  868.                 "DW_DLA_CIE",
  869.                 "DW_DLA_FDE",
  870.                 "DW_DLA_LOC_BLOCK",
  871.                 "DW_DLA_FRAME_BLOCK",
  872.                 "DW_DLA_FUNC",
  873.                 "DW_DLA_TYPENAME",
  874.                 "DW_DLA_VAR",
  875.                 "DW_DLA_WEAK",
  876.                 "DW_DLA_ADDR",
  877.                 "DW_DLA_ABBREV_LIST",
  878.                 "DW_DLA_CHAIN",
  879.                 "DW_DLA_CU_CONTEXT",
  880.                 "DW_DLA_FRAME",
  881.                 "DW_DLA_GLOBAL_CONTEXT",
  882.                 "DW_DLA_FILE_ENTRY",
  883.                 "DW_DLA_LINE_CONTEXT",
  884.                 "DW_DLA_LOC_CHAIN",
  885.                 "DW_DLA_HASH_TABLE",
  886.                 "DW_DLA_FUNC_CONTEXT",
  887.                 "DW_DLA_TYPENAME_CONTEXT",
  888.                 "DW_DLA_VAR_CONTEXT"
  889.                 "DW_DLA_WEAK_CONTEXT"
  890.             };
  891.  
  892.     if (dbg == NULL) return;
  893.  
  894.     if (dbg->de_alloc_hdr == NULL) return;
  895.  
  896.     printf("Alloc Type                   Max    Curr  Structs\n");
  897.     printf("----------                   ---    ----  -------\n");
  898.     for (i = 1; i <= MAX_DW_DLA; i++) {
  899.     alloc_hdr = dbg->de_alloc_hdr[i];
  900.  
  901.     if (alloc_hdr != NULL) {
  902.         printf("%-25s %6d  %6d %8d\n", alloc_type_name[i], 
  903.             alloc_hdr->ah_max_alloc, alloc_hdr->ah_curr_alloc,
  904.         alloc_hdr->ah_struct_alloc_count);
  905.     }
  906.     }
  907. }
  908.  
  909.  
  910. /*
  911.     This function is used to recursively
  912.     free the chunks still allocated, and
  913.     forward chained through the aa_next
  914.     pointer.
  915. */
  916. _dwarf_recursive_free (
  917.     Dwarf_Alloc_Area    alloc_area
  918. )
  919. {
  920.     if (alloc_area->aa_next != NULL)
  921.     _dwarf_recursive_free(alloc_area->aa_next);
  922.  
  923.     free(alloc_area);
  924. }
  925.  
  926.  
  927. /*
  928.     Used to free all space allocated for this Dwarf_Debug.
  929.     The caller should assume that the Dwarf_Debug pointer 
  930.     itself is no longer valid upon return from this function.
  931.  
  932.     In case of difficulty, this function simply returns quietly.
  933. */
  934. int
  935. _dwarf_free_all_of_one_debug (
  936.     Dwarf_Debug     dbg
  937. )
  938. {
  939.     Dwarf_Alloc_Hdr    alloc_hdr;
  940.     Dwarf_Shalf        i;
  941.  
  942.     if (dbg == NULL) return(DW_DLV_ERROR);
  943.  
  944.     if (dbg->de_alloc_hdr == NULL) return(DW_DLV_ERROR);
  945.  
  946.     for (i = 1; i <= MAX_DW_DLA; i++) {
  947.     alloc_hdr = dbg->de_alloc_hdr[i];
  948.  
  949.     if (alloc_hdr != NULL) {
  950.  
  951.         if (alloc_hdr->ah_alloc_area_head != NULL)
  952.         _dwarf_recursive_free(alloc_hdr->ah_alloc_area_head);
  953.  
  954.         free(alloc_hdr);
  955.     }
  956.     }
  957.  
  958.     free(dbg);
  959.     return(DW_DLV_OK);
  960. }
  961.  
  962.  
  963. /*
  964.     The application calls dwarf_transform_to_disk_form()
  965.     and that function, when it has done its work, calls
  966.     this function to free all it can.
  967.  
  968.     Leaving byte streams and other minimal support structure
  969.     in memory.
  970.  
  971. */
  972. void 
  973. _dwarf_free_after_transform_to_disk (
  974.     Dwarf_Debug     dbg
  975. )
  976. {
  977.     return;
  978. }
  979.