Example #1
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;
}
Example #2
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;
}