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;
    int i = 0;
    Dwarf_Error erre = 0;
    Dwarf_Error *error = &erre;
    Dwarf_Signed sec_count = 0;

    for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) {
        Dwarf_P_Per_Reloc_Sect p_reloc = dbg->de_reloc_sect +i;
        Dwarf_Small *data = 0;
        int sec_index = 0;
        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_callback_func or de_callback_func_b or _c, getting
                section number of reloc section. */
            int rel_section_index = 0;
            Dwarf_Unsigned name_idx = 0;
            int erri = 0;

            if (dbg->de_callback_func) {
                rel_section_index =
                    dbg->de_callback_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],
                        &name_idx,
                        dbg->de_user_data,
                        &erri);
            }
            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, &erri);
        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 lenk =
                p_blk->rb_where_to_add_next - p_blk->rb_data;

            memcpy(data, p_blk->rb_data, lenk);
            data += lenk;
            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;
}