/* 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; }
/* 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; }