예제 #1
0
int
_dwarf_pro_transform_macro_info_to_disk(Dwarf_P_Debug dbg,
					Dwarf_Error * error)
{
    /* Total num of bytes in .debug_macinfo section. */
    Dwarf_Unsigned mac_num_bytes;

    /* Points to first byte of .debug_macinfo buffer. */
    Dwarf_Small *macinfo;

    /* Fills in the .debug_macinfo buffer. */
    Dwarf_Small *macinfo_ptr;


    /* Used to scan the section data buffers. */
    struct dw_macinfo_block_s *m_prev;
    struct dw_macinfo_block_s *m_sect;


    /* Get the size of the debug_macinfo data */
    mac_num_bytes = 0;
    for (m_sect = dbg->de_first_macinfo; m_sect != NULL;
	 m_sect = m_sect->mb_next) {
	mac_num_bytes += m_sect->mb_used_len;
    }
    /* Tthe final entry has a type code of 0 to indicate It is final
       for this CU Takes just 1 byte. */
    mac_num_bytes += 1;

    GET_CHUNK(dbg, dbg->de_elf_sects[DEBUG_MACINFO],
	      macinfo, (unsigned long) mac_num_bytes, error);
    if (macinfo == NULL) {
	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
	return (0);
    }

    macinfo_ptr = macinfo;
    m_prev = 0;
    for (m_sect = dbg->de_first_macinfo; m_sect != NULL;
	 m_sect = m_sect->mb_next) {
	memcpy(macinfo_ptr, m_sect->mb_data, m_sect->mb_used_len);
	macinfo_ptr += m_sect->mb_used_len;
	if (m_prev) {
	    _dwarf_p_dealloc(dbg, (Dwarf_Small *) m_prev);
	    m_prev = 0;
	}
	m_prev = m_sect;
    }
    *macinfo_ptr = 0;		/* the type code of 0 as last entry */
    if (m_prev) {
	_dwarf_p_dealloc(dbg, (Dwarf_Small *) m_prev);
	m_prev = 0;
    }

    return (int) dbg->de_n_debug_sect;
}
예제 #2
0
void
_dwarf_p_dealloc_all(Dwarf_P_Debug dbg)
{
    memory_list_t *dbglp;

    if (dbg == NULL) {
        /* should throw an error */
        return;
    }

    dbglp = BLOCK_TO_LIST(dbg);
    while (dbglp->next != dbglp) {
        _dwarf_p_dealloc(dbg, LIST_TO_BLOCK(dbglp->next));
    }
    if (dbglp->next != dbglp ||
        dbglp->prev != dbglp) {

        /* should throw error */
        /* For some reason we couldn't free all the blocks? */
        return;
    }
    _dwarf_p_dealloc(NULL, (void*)dbg);
}
예제 #3
0
/* 
        Ensure each stream is a single buffer and
        add that single buffer to the set of stream buffers.

        By creating a new buffer and copying if necessary.

        Free the input set of buffers if we consolidate.
        Return -1 on error (malloc failure)


        Return DW_DLV_OK on success. Any other return indicates 
        malloc failed.
        
*/
int
_dwarf_stream_relocs_to_disk(Dwarf_P_Debug dbg,
    Dwarf_Signed * new_sec_count)
{
    unsigned long total_size = 0;
    Dwarf_Small *data = 0;
    int sec_index = 0;
    unsigned long i = 0;
    Dwarf_Error err = 0;
    Dwarf_Error *error = &err;

    Dwarf_Signed sec_count = 0;

    Dwarf_P_Per_Reloc_Sect p_reloc = &dbg->de_reloc_sect[0];

    for (i = 0; i < NUM_DEBUG_SECTIONS; ++i, ++p_reloc) {
        unsigned long ct = p_reloc->pr_reloc_total_count;
        unsigned len = 0;
        struct Dwarf_P_Relocation_Block_s *p_blk = 0;
        struct Dwarf_P_Relocation_Block_s *p_blk_last = 0;
        Dwarf_P_Per_Reloc_Sect prb = 0;

        if (ct == 0) {
            continue;
        }
        prb = &dbg->de_reloc_sect[i];
        len = dbg->de_relocation_record_size;
        ++sec_count;

        total_size = ct * len;
        sec_index = prb->pr_sect_num_of_reloc_sect;
        if (sec_index == 0) {
            /* call de_func or de_func_b, getting section number of
               reloc sec */
            int rel_section_index = 0;
            Dwarf_Unsigned name_idx = 0;
            int int_name = 0;
            int err = 0;

            if (dbg->de_func_b) {
                rel_section_index =
                    dbg->de_func_b(_dwarf_rel_section_names[i],
                                   /* size */
                                   dbg->de_relocation_record_size,
                                   /* type */ SHT_REL,
                                   /* flags */ 0,
                                   /* link to symtab, which we cannot
                                      know */ 0,
                                   /* info == link to sec rels apply to 
                                    */
                                   dbg->de_elf_sects[i],
                                   &name_idx, &err);
            } else {
                rel_section_index =
                    dbg->de_func(_dwarf_rel_section_names[i],
                                 /* size */
                                 dbg->de_relocation_record_size,
                                 /* type */ SHT_REL,
                                 /* flags */ 0,
                                 /* link to symtab, which we cannot
                                    know */ 0,
                                 /* info == link to sec rels apply to */
                                 dbg->de_elf_sects[i], &int_name, &err);
                name_idx = int_name;
            }
            if (rel_section_index == -1) {
                {
                    _dwarf_p_error(dbg, error, DW_DLE_ELF_SECT_ERR);
                    return (DW_DLV_ERROR);
                }

            }
            prb->pr_sect_num_of_reloc_sect = rel_section_index;
            sec_index = rel_section_index;
        }
        GET_CHUNK(dbg, sec_index, data, total_size, &err);
        p_blk = p_reloc->pr_first_block;

        /* following loop executes at least once. Effects the
           consolidation to a single block or, if already a single
           block, simply copies to the output buffer. And frees the
           input block. The new block is in the de_debug_sects list. */
        while (p_blk) {

            unsigned long len =
                p_blk->rb_where_to_add_next - p_blk->rb_data;

            memcpy(data, p_blk->rb_data, len);


            data += len;

            p_blk_last = p_blk;
            p_blk = p_blk->rb_next;

            _dwarf_p_dealloc(dbg, (Dwarf_Small *) p_blk_last);
        }
        /* ASSERT: sum of len copied == total_size */

        /* 
           We have copied the input, now drop the pointers to it. For
           debugging, leave the other data untouched. */
        p_reloc->pr_first_block = 0;
        p_reloc->pr_last_block = 0;
    }

    *new_sec_count = sec_count;
    return DW_DLV_OK;
}
예제 #4
0
Dwarf_P_Attribute
dwarf_add_AT_block(
    Dwarf_P_Debug       dbg,
    Dwarf_P_Die         ownerdie,
    Dwarf_Half          attr,
    Dwarf_Small         *block_data,
    Dwarf_Unsigned      block_size,
    Dwarf_Error         *error
)
{
    Dwarf_P_Attribute   new_attr = 0;
    int result = 0;
    char encode_buffer[ENCODE_SPACE_NEEDED];
    int len_size = 0;
    char * attrdata = 0;

    if (dbg == NULL) {
        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
    }

    if (ownerdie == NULL) {
        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
    }

    /* I don't mess with block1, block2, block4, not worth the effort */

    /* So, encode the length into LEB128 */
    result = _dwarf_pro_encode_leb128_nm(block_size, &len_size,
        encode_buffer,sizeof(encode_buffer));
    if (result !=  DW_DLV_OK) {
        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
    }

    /* Allocate the new attribute */
    new_attr = (Dwarf_P_Attribute)
        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
    if (new_attr == NULL) {
        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
    }

    /* Fill in the attribute */
    new_attr->ar_attribute = attr;
    new_attr->ar_attribute_form = DW_FORM_block;
    new_attr->ar_nbytes = len_size + block_size;
    new_attr->ar_next = 0;

    new_attr->ar_data = attrdata = (char *)
        _dwarf_p_get_alloc(dbg, len_size + block_size);
    if (new_attr->ar_data == NULL) {
        /* free the block we got earlier */
        _dwarf_p_dealloc(dbg, (unsigned char *) new_attr);
        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
    }

    /* write length and data to attribute data buffer */
    memcpy(attrdata, encode_buffer, len_size);
    attrdata += len_size;
    memcpy(attrdata, block_data, block_size);

    /* add attribute to the die */
    _dwarf_pro_add_at_to_die(ownerdie, new_attr);

    return new_attr;
}
예제 #5
0
void
dwarf_dealloc_compressed_block(Dwarf_P_Debug dbg, void * space)
{
    _dwarf_p_dealloc(dbg, space);
}
예제 #6
0
void *
dwarf_compress_integer_block(
    Dwarf_P_Debug    dbg,
    Dwarf_Bool       unit_is_signed,
    Dwarf_Small      unit_length_in_bits,
    void*            input_block,
    Dwarf_Unsigned   input_length_in_units,
    Dwarf_Unsigned*  output_length_in_bytes_ptr,
    Dwarf_Error*     error
)
{
    Dwarf_Unsigned output_length_in_bytes = 0;
    char * output_block = 0;
    char encode_buffer[ENCODE_SPACE_NEEDED];
    unsigned u = 0;
    char * ptr = 0;
    int remain = 0;
    int result = 0;

    if (dbg == NULL) {
        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
        return((void *)DW_DLV_BADADDR);
    }

    if (unit_is_signed == false ||
        unit_length_in_bits != 32 ||
        input_block == NULL ||
        input_length_in_units == 0 ||
        output_length_in_bytes_ptr == NULL) {
        _dwarf_p_error(NULL, error, DW_DLE_BADBITC);
        return ((void *) DW_DLV_BADADDR);
    }

    /* At this point we assume the format is: signed 32 bit */

    /* First compress everything to find the total size. */

    output_length_in_bytes = 0;
    for (u=0; u<input_length_in_units; u++) {
        int unit_encoded_size;
        Dwarf_sfixed unit; /* this is fixed at signed-32-bits */

        unit = ((Dwarf_sfixed*)input_block)[u];

        result = _dwarf_pro_encode_signed_leb128_nm(unit, &unit_encoded_size,
            encode_buffer,sizeof(encode_buffer));
        if (result !=  DW_DLV_OK) {
            _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
            return((Dwarf_P_Attribute)DW_DLV_BADADDR);
        }
        output_length_in_bytes += unit_encoded_size;
    }


    /* Then alloc */

    output_block = (void *)
        _dwarf_p_get_alloc(dbg, output_length_in_bytes);
    if (output_block == NULL) {
        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
        return((void*)DW_DLV_BADADDR);
    }

    /* Then compress again and copy into new buffer */

    ptr = output_block;
    remain = output_length_in_bytes;
    for (u=0; u<input_length_in_units; u++) {
        int unit_encoded_size;
        Dwarf_sfixed unit; /* this is fixed at signed-32-bits */

        unit = ((Dwarf_sfixed*)input_block)[u];

        result = _dwarf_pro_encode_signed_leb128_nm(unit, &unit_encoded_size,
            ptr, remain);
        if (result !=  DW_DLV_OK) {
            _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
            return((Dwarf_P_Attribute)DW_DLV_BADADDR);
        }
        remain -= unit_encoded_size;
        ptr += unit_encoded_size;
    }

    if (remain != 0) {
        _dwarf_p_dealloc(dbg, (unsigned char *)output_block);
        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
    }

    *output_length_in_bytes_ptr = output_length_in_bytes;
    return (void*) output_block;

}
예제 #7
0
/*
        Ensure each stream is a single buffer and
        add that single buffer to the set of stream buffers.

	By creating a new buffer and copying if necessary.
	(If > 1 block, reduce to 1 block)

        Free the input set of buffers if we consolidate.

	We pass back *new_sec_count as zero because we
        are not creating normal sections for a .o, but
	symbolic relocations, separately counted.

        Return -1 on error (malloc failure)


        Return DW_DLV_OK on success. Any other return indicates 
	malloc failed.
*/
int
_dwarf_symbolic_relocs_to_disk(Dwarf_P_Debug dbg,
			       Dwarf_Signed * new_sec_count)
{
    /* unsigned long total_size =0; */
    Dwarf_Small *data;
    int sec_index;
    int res;
    unsigned long i;
    Dwarf_Error error;

    Dwarf_Signed sec_count = 0;

    Dwarf_P_Per_Reloc_Sect p_reloc = &dbg->de_reloc_sect[0];

    for (i = 0; i < NUM_DEBUG_SECTIONS; ++i, ++p_reloc) {

	unsigned long ct = p_reloc->pr_reloc_total_count;
	struct Dwarf_P_Relocation_Block_s *p_blk;
	struct Dwarf_P_Relocation_Block_s *p_blk_last;

	/* int len */
	int err;


	if (ct == 0) {
	    continue;
	}

	/* len = dbg->de_relocation_record_size; */
	++sec_count;

	/* total_size = ct *len; */
	sec_index = p_reloc->pr_sect_num_of_reloc_sect;
	if (sec_index == 0) {
	    /* call de_func or de_func_b, getting section number of
	       reloc sec */
	    int rel_section_index;
	    int int_name;
	    Dwarf_Unsigned name_idx;

	    /* 
	       This is a bit of a fake, as we do not really have true
	       elf sections at all. Just the data such might contain.
	       But this lets the caller eventually link things
	       together: without this call we would not know what rel
	       data goes with what section when we are asked for the
	       real arrays. */

	    if (dbg->de_func_b) {
		rel_section_index =
		    dbg->de_func_b(_dwarf_rel_section_names[i],
				   dbg->de_relocation_record_size,
				   /* type */ SHT_REL,
				   /* flags */ 0,
				   /* link to symtab, which we cannot
				      know */ SHN_UNDEF,
				   /* sec rels apply to */
				   dbg->de_elf_sects[i],
				   &name_idx, &err);
	    } else {
		rel_section_index =
		    dbg->de_func(_dwarf_rel_section_names[i],
				 dbg->de_relocation_record_size,
				 /* type */ SHT_REL,
				 /* flags */ 0,
				 /* link to symtab, which we cannot
				    know */ SHN_UNDEF,
				 /* sec rels apply to, in elf, sh_info */
				 dbg->de_elf_sects[i], &int_name, &err);
		name_idx = int_name;
	    }
	    if (rel_section_index == -1) {
		{
		    _dwarf_p_error(dbg, &error, DW_DLE_ELF_SECT_ERR);
		    return (DW_DLV_ERROR);
		}
	    }
	    p_reloc->pr_sect_num_of_reloc_sect = rel_section_index;
	    sec_index = rel_section_index;
	}

	p_blk = p_reloc->pr_first_block;

	if (p_reloc->pr_block_count > 1) {
	    struct Dwarf_P_Relocation_Block_s *new_blk;

	    /* HACK , not normal interfaces, trashing p_reloc
	       current contents! */
	    _dwarf_reset_reloc_sect_info(p_reloc, ct);

	    /* Creating new single block for all 'ct' entries */
	    res = _dwarf_pro_pre_alloc_n_reloc_slots(dbg, (int) i, ct);


	    if (res != DW_DLV_OK) {
		return res;
	    }
	    new_blk = p_reloc->pr_first_block;

	    data = (Dwarf_Small *) new_blk->rb_data;

	    /* The following loop does the consolidation to a 
	       single block and frees the input block(s). */
	    do {

		unsigned long len =
		    p_blk->rb_where_to_add_next - p_blk->rb_data;

		memcpy(data, p_blk->rb_data, len);
		data += len;

		p_blk_last = p_blk;
		p_blk = p_blk->rb_next;

		_dwarf_p_dealloc(dbg, (Dwarf_Small *) p_blk_last);
	    } while (p_blk) ;
	    /* ASSERT: sum of len copied == total_size */
	    new_blk->rb_next_slot_to_use = ct;
	    new_blk->rb_where_to_add_next = (char *) data;
	    p_reloc->pr_reloc_total_count = ct;

	    /* have now created a single block, but no change in slots
	       used (pr_reloc_total_count) */
	}
    }

    *new_sec_count = 0;
    return DW_DLV_OK;
}