#include "config.h"
#include "libdwarfdefs.h"
#include <stdio.h>
#include <string.h>
#include "pro_incl.h"
int
_dwarf_pro_pre_alloc_n_reloc_slots(Dwarf_P_Debug dbg,
int rel_sec_index,
Dwarf_Unsigned newslots)
{
unsigned long len;
struct Dwarf_P_Relocation_Block_s *data;
Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[rel_sec_index];
unsigned long slots_in_blk = (unsigned long) newslots;
unsigned long rel_rec_size = dbg->de_relocation_record_size;
if (prel->pr_first_block)
return DW_DLV_OK;
len = sizeof(struct Dwarf_P_Relocation_Block_s) +
slots_in_blk * rel_rec_size;
data = (struct Dwarf_P_Relocation_Block_s *)
_dwarf_p_get_alloc(dbg, len);
if (!data) {
return DW_DLV_ERROR;
}
data->rb_slots_in_block = slots_in_blk;
data->rb_next_slot_to_use = 0;
data->rb_where_to_add_next =
((char *) data) + sizeof(struct Dwarf_P_Relocation_Block_s);
data->rb_data = data->rb_where_to_add_next;
prel->pr_first_block = data;
prel->pr_last_block = data;
prel->pr_block_count = 1;
return DW_DLV_OK;
}
int
_dwarf_pro_alloc_reloc_slots(Dwarf_P_Debug dbg, int rel_sec_index)
{
unsigned long len;
struct Dwarf_P_Relocation_Block_s *data;
Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[rel_sec_index];
unsigned long slots_in_blk = prel->pr_slots_per_block_to_alloc;
unsigned long rel_rec_size = dbg->de_relocation_record_size;
len = sizeof(struct Dwarf_P_Relocation_Block_s) +
slots_in_blk * rel_rec_size;
data = (struct Dwarf_P_Relocation_Block_s *)
_dwarf_p_get_alloc(dbg, len);
if (!data) {
return DW_DLV_ERROR;
}
if (prel->pr_first_block) {
prel->pr_last_block->rb_next = data;
prel->pr_last_block = data;
prel->pr_block_count += 1;
} else {
prel->pr_first_block = data;
prel->pr_last_block = data;
prel->pr_block_count = 1;
}
data->rb_slots_in_block = slots_in_blk;
data->rb_next_slot_to_use = 0;
data->rb_where_to_add_next =
((char *) data) + sizeof(struct Dwarf_P_Relocation_Block_s);
data->rb_data = data->rb_where_to_add_next;
return DW_DLV_OK;
}
int
_dwarf_pro_reloc_get_a_slot(Dwarf_P_Debug dbg,
int base_sec_index, void **relrec_to_fill)
{
struct Dwarf_P_Relocation_Block_s *data;
Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[base_sec_index];
unsigned long rel_rec_size = dbg->de_relocation_record_size;
char *ret_addr;
data = prel->pr_last_block;
if ((data == 0) ||
(data->rb_next_slot_to_use >= data->rb_slots_in_block)) {
int res;
res = _dwarf_pro_alloc_reloc_slots(dbg, base_sec_index);
if (res != DW_DLV_OK) {
return res;
}
}
data = prel->pr_last_block;
ret_addr = data->rb_where_to_add_next;
data->rb_where_to_add_next += rel_rec_size;
data->rb_next_slot_to_use += 1;
prel->pr_reloc_total_count += 1;
*relrec_to_fill = (void *) ret_addr;
return DW_DLV_OK;
}
int
dwarf_get_relocation_info_count(Dwarf_P_Debug dbg,
Dwarf_Unsigned *
count_of_relocation_sections,
int *drd_buffer_version,
Dwarf_Error * error)
{
if (dbg->de_flags & DW_DLC_SYMBOLIC_RELOCATIONS) {
int i;
unsigned int count = 0;
for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) {
if (dbg->de_reloc_sect[i].pr_reloc_total_count > 0) {
++count;
}
}
*count_of_relocation_sections = (Dwarf_Unsigned) count;
*drd_buffer_version = DWARF_DRD_BUFFER_VERSION;
return DW_DLV_OK;
}
return DW_DLV_NO_ENTRY;
}
int
dwarf_get_relocation_info(Dwarf_P_Debug dbg,
Dwarf_Signed * elf_section_index,
Dwarf_Signed * elf_section_index_link,
Dwarf_Unsigned * relocation_buffer_count,
Dwarf_Relocation_Data * reldata_buffer,
Dwarf_Error * error)
{
int next = dbg->de_reloc_next_to_return;
if (dbg->de_flags & DW_DLC_SYMBOLIC_RELOCATIONS) {
int i;
for (i = next; i < NUM_DEBUG_SECTIONS; ++i) {
Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[i];
if (prel->pr_reloc_total_count > 0) {
dbg->de_reloc_next_to_return = i + 1;
*elf_section_index = prel->pr_sect_num_of_reloc_sect;
*elf_section_index_link = dbg->de_elf_sects[i];
*relocation_buffer_count = prel->pr_reloc_total_count;
*reldata_buffer = (Dwarf_Relocation_Data)
(prel->pr_first_block->rb_data);
return DW_DLV_OK;
}
}
DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR);
}
return DW_DLV_NO_ENTRY;
}