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

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <elfaccess.h>
  4. #include "pro_incl.h"
  5. #include "pro_arange.h"
  6. #include "pro_section.h"
  7.  
  8. #define GET_DISP(dbg,val) (IS_64BIT(dbg) ? (char *)&val : ((char *)&val + 4))
  9.  
  10. extern int elf_sects[NUM_DEBUG_SECTIONS];
  11. extern int sect_name_idx[NUM_DEBUG_SECTIONS];
  12. extern int reloc_sects[NUM_DEBUG_SECTIONS];
  13.  
  14. /*
  15.     This function adds another address range 
  16.     to the list of address ranges for the
  17.     given Dwarf_P_Debug.  It returns 0 on error,
  18.     and 1 otherwise.
  19. */
  20. Dwarf_Unsigned 
  21. dwarf_add_arange (
  22.     Dwarf_P_Debug    dbg,
  23.     Dwarf_Addr        begin_address,
  24.     Dwarf_Unsigned    length,
  25.     Dwarf_Signed    symbol_index,
  26.     Dwarf_Error        *error
  27. )
  28. {
  29.     Dwarf_P_Arange    arange;
  30.  
  31.     if (dbg == NULL) {
  32.     _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
  33.     return(0);
  34.     }
  35.  
  36.     arange = (Dwarf_P_Arange)
  37.     _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Arange_s));
  38.     if (arange == NULL) {
  39.     _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
  40.     return(0);
  41.     }
  42.  
  43.     arange->ag_begin_address = begin_address;
  44.     arange->ag_length = length;
  45.     arange->ag_symbol_index = symbol_index;
  46.  
  47.     if (dbg->de_arange == NULL)
  48.     dbg->de_arange = dbg->de_last_arange = arange;
  49.     else {
  50.     dbg->de_last_arange->ag_next = arange;
  51.     dbg->de_last_arange = arange;
  52.     }
  53.     dbg->de_arange_count++;
  54.  
  55.     return(1);
  56. }
  57.  
  58.  
  59. int
  60. _dwarf_transform_arange_to_disk (
  61.     Dwarf_P_Debug        dbg,
  62.     Dwarf_Error        *error
  63. )
  64. {
  65.     /* Total num of bytes in .debug_aranges section. */
  66.     Dwarf_Unsigned    arange_num_bytes;
  67.  
  68.     /* 
  69.         Adjustment to align the start of the actual
  70.         address ranges on a boundary aligned with
  71.         twice the address size.
  72.     */
  73.     Dwarf_Small        remainder;
  74.  
  75.     /* Total number of bytes excluding the length field. */
  76.     Dwarf_Unsigned    adjusted_length;
  77.  
  78.     /* Total num of bytes in .rel.debug_aranges section. */
  79.     Dwarf_Unsigned    arange_reloc_num_bytes;
  80.  
  81.     /* Points to first byte of .debug_aranges buffer. */
  82.     Dwarf_Small        *arange;
  83.  
  84.     /* Fills in the .debug_aranges buffer. */
  85.     Dwarf_Small        *arange_ptr;
  86.  
  87.     /* Points to first byte of .rel.debug_aranges section. */
  88.     Dwarf_Small        *arange_reloc;
  89.  
  90.     /* Fills in the .rel.debug_aranges section. */
  91.     Dwarf_Small        *arange_reloc_ptr;
  92.  
  93.     /* Scans the list of address ranges provided by user. */
  94.     Dwarf_P_Arange    given_arange;
  95.  
  96.     /* Used to fill in 0. */
  97.     const Dwarf_Signed    big_zero = 0;
  98.  
  99.     /* Points to a Elf64_Rel record. */
  100.     Elf64_Rel        *elf64_reloc;
  101.  
  102.     /* Points to a Elf32_Rel record. */
  103.     Elf32_Rel        *elf32_reloc;
  104.  
  105.     int            name_idx;
  106.     int            err;
  107.  
  108.     /* ***** BEGIN CODE ***** */
  109.  
  110.     /* Size of the .debug_aranges section header. */
  111.     arange_num_bytes = SIZEOF_UWORD(dbg) +  /* Size of length field. */
  112.     sizeof(Dwarf_Half) +             /* Size of version field. */
  113.     SIZEOF_UWORD(dbg) +             /* Size of .debug_info offset. */
  114.     sizeof(Dwarf_Small) +             /* Size of address size field. */
  115.     sizeof(Dwarf_Small);             /* Size of segment size field. */
  116.  
  117.     /* 
  118.         Adjust the size so that the set of aranges begins on
  119.         a boundary that aligned with twice the address size.  This
  120.         is a Libdwarf requirement.
  121.     */
  122.     remainder = arange_num_bytes % (2 * SIZEOF_UWORD(dbg));
  123.     if (remainder != 0)
  124.         arange_num_bytes += (2*SIZEOF_UWORD(dbg)) - remainder;
  125.  
  126.  
  127.     /* Add the bytes for the actual address ranges. */
  128.     arange_num_bytes += SIZEOF_UWORD(dbg) * 2 * (dbg->de_arange_count + 1);
  129.  
  130.     GET_NEW_CHUNK(dbg, elf_sects[DEBUG_ARANGES], arange, arange_num_bytes, 
  131.     error);
  132.     arange_ptr = arange;
  133.     if (arange == NULL)
  134.     {_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return(0);}
  135.  
  136.     /* Write the total length of .debug_aranges section. */
  137.     adjusted_length = arange_num_bytes - SIZEOF_UWORD(dbg);
  138.     memcpy(arange_ptr, GET_DISP(dbg, adjusted_length), SIZEOF_UWORD(dbg));
  139.     arange_ptr += SIZEOF_UWORD(dbg);
  140.  
  141.     /* Write the version as 2 bytes. */
  142.     *arange_ptr = 0;
  143.     arange_ptr++;
  144.     *arange_ptr = CURRENT_VERSION_STAMP;
  145.     arange_ptr++;
  146.  
  147.     /* Write the .debug_info offset.  This is always 0. */
  148.     memcpy(arange_ptr, GET_DISP(dbg, big_zero), SIZEOF_UWORD(dbg));
  149.     arange_ptr += SIZEOF_UWORD(dbg);
  150.  
  151.     /* Write the size of addresses. */
  152.     *arange_ptr = IS_64BIT(dbg) ? 8 : 4;
  153.     arange_ptr++;
  154.  
  155.     /* 
  156.         Write the size of segment addresses.  
  157.         This is zero for MIPS architectures.
  158.     */
  159.     *arange_ptr = 0;
  160.     arange_ptr++;
  161.  
  162.     /* 
  163.         Skip over the padding to align the start of the 
  164.         actual address ranges to twice the address size.
  165.     */
  166.     if (remainder != 0)
  167.         arange_ptr += (2*SIZEOF_UWORD(dbg)) - remainder;
  168.  
  169.     arange_reloc_num_bytes = 
  170.     (IS_64BIT(dbg) ? sizeof(Elf64_Rel) : sizeof(Elf32_Rel)) * 
  171.     (dbg->de_arange_count + 1);
  172.  
  173.     reloc_sects[DEBUG_ARANGES] = dbg->de_func(".rel.debug_aranges",
  174.     IS_64BIT(dbg), SHT_REL, 0, SHN_UNDEF,elf_sects[DEBUG_ARANGES], 
  175.     &name_idx, &err);
  176.     if (reloc_sects[DEBUG_ARANGES] == -1) {
  177.         DWARF_P_DBG_ERROR(dbg,DW_DLE_ELF_SECT_ERR,DW_DLV_NOCOUNT);
  178.     }
  179.  
  180.     GET_NEW_CHUNK (dbg, reloc_sects[DEBUG_ARANGES], arange_reloc, 
  181.     arange_reloc_num_bytes, error);
  182.     arange_reloc_ptr = arange_reloc;
  183.     if (arange_reloc == NULL) 
  184.     {_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return(0);}
  185.  
  186.     /* Write relocation record for .debug_info offset. */
  187.     if (IS_64BIT(dbg)) {
  188.     elf64_reloc = (Elf64_Rel *)arange_reloc_ptr;
  189.     elf64_reloc->r_offset = SIZEOF_UWORD(dbg) + sizeof(Dwarf_Half);
  190.     Set_REL64_info(*elf64_reloc, sect_name_idx[DEBUG_INFO], R_MIPS_64);
  191.     arange_reloc_ptr += sizeof(Elf64_Rel);
  192.     }
  193.     else {
  194.     elf32_reloc = (Elf32_Rel *)arange_reloc_ptr;
  195.     elf32_reloc->r_offset = SIZEOF_UWORD(dbg) + sizeof(Dwarf_Half);
  196.     Set_REL32_info(*elf32_reloc, sect_name_idx[DEBUG_INFO], R_MIPS_32);
  197.     arange_reloc_ptr += sizeof(Elf32_Rel);
  198.     }
  199.  
  200.  
  201.     for (given_arange = dbg->de_arange; given_arange != NULL;
  202.     given_arange = given_arange->ag_next) {
  203.  
  204.         /* Write relocation record for beginning of address range. */
  205.     if (IS_64BIT(dbg)) {
  206.         elf64_reloc = (Elf64_Rel *)arange_reloc_ptr;
  207.         elf64_reloc->r_offset = arange_ptr - arange;
  208.         Set_REL64_info
  209.         (*elf64_reloc, given_arange->ag_symbol_index, R_MIPS_64);
  210.         arange_reloc_ptr += sizeof(Elf64_Rel);
  211.     }
  212.     else {
  213.         elf32_reloc = (Elf32_Rel *)arange_reloc_ptr;
  214.         elf32_reloc->r_offset = arange_ptr - arange;
  215.         Set_REL32_info
  216.         (*elf32_reloc, given_arange->ag_symbol_index, R_MIPS_32);
  217.         arange_reloc_ptr += sizeof(Elf32_Rel);
  218.     }
  219.  
  220.         /* Copy beginning address of range. */
  221.     memcpy(arange_ptr, GET_DISP(dbg, given_arange->ag_begin_address),
  222.         SIZEOF_UWORD(dbg));
  223.     arange_ptr += SIZEOF_UWORD(dbg);
  224.  
  225.         /* Copy length of range. */
  226.     memcpy(arange_ptr, GET_DISP(dbg, given_arange->ag_length), 
  227.         SIZEOF_UWORD(dbg));
  228.     arange_ptr += SIZEOF_UWORD(dbg);
  229.     }
  230.  
  231.     memcpy(arange_ptr, GET_DISP(dbg, big_zero), SIZEOF_UWORD(dbg));
  232.     arange_ptr += SIZEOF_UWORD(dbg);
  233.     memcpy(arange_ptr, GET_DISP(dbg, big_zero), SIZEOF_UWORD(dbg));
  234.  
  235.     return dbg->de_n_debug_sect;
  236. }
  237.