#include "config.h"
#include "libdwarfdefs.h"
#include <stdio.h>
#include <string.h>
#ifdef HAVE_ELFACCESS_H
#include <elfaccess.h>
#endif
#include "pro_incl.h"
#include "pro_arange.h"
#include "pro_section.h"
#include "pro_reloc.h"
Dwarf_Unsigned
dwarf_add_arange(Dwarf_P_Debug dbg,
Dwarf_Addr begin_address,
Dwarf_Unsigned length,
Dwarf_Signed symbol_index, Dwarf_Error * error)
{
return dwarf_add_arange_b(dbg, begin_address, length, symbol_index,
0,
0,
error);
}
Dwarf_Unsigned
dwarf_add_arange_b(Dwarf_P_Debug dbg,
Dwarf_Addr begin_address,
Dwarf_Unsigned length,
Dwarf_Unsigned symbol_index,
Dwarf_Unsigned end_symbol_index,
Dwarf_Addr offset_from_end_sym, Dwarf_Error * error)
{
Dwarf_P_Arange arange;
if (dbg == NULL) {
_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
return (0);
}
arange = (Dwarf_P_Arange)
_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Arange_s));
if (arange == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return (0);
}
arange->ag_begin_address = begin_address;
arange->ag_length = length;
arange->ag_symbol_index = symbol_index;
arange->ag_end_symbol_index = end_symbol_index;
arange->ag_end_symbol_offset = offset_from_end_sym;
if (dbg->de_arange == NULL)
dbg->de_arange = dbg->de_last_arange = arange;
else {
dbg->de_last_arange->ag_next = arange;
dbg->de_last_arange = arange;
}
dbg->de_arange_count++;
return (1);
}
int
_dwarf_transform_arange_to_disk(Dwarf_P_Debug dbg, Dwarf_Error * error)
{
Dwarf_Unsigned arange_num_bytes;
Dwarf_Small remainder;
Dwarf_Unsigned adjusted_length;
Dwarf_Small *arange;
Dwarf_Small *arange_ptr;
Dwarf_P_Arange given_arange;
const Dwarf_Signed big_zero = 0;
int extension_word_size = dbg->de_64bit_extension ? 4 : 0;
int uword_size = dbg->de_offset_size;
int upointer_size = dbg->de_pointer_size;
int res;
arange_num_bytes = extension_word_size + uword_size +
sizeof(Dwarf_Half) +
uword_size +
sizeof(Dwarf_Small) +
sizeof(Dwarf_Small);
remainder = arange_num_bytes % (2 * upointer_size);
if (remainder != 0)
arange_num_bytes += (2 * upointer_size) - remainder;
arange_num_bytes += upointer_size * 2 * (dbg->de_arange_count + 1);
GET_CHUNK(dbg, dbg->de_elf_sects[DEBUG_ARANGES],
arange, (unsigned long) arange_num_bytes, error);
arange_ptr = arange;
if (arange == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return (0);
}
if (extension_word_size) {
Dwarf_Word x = DISTINGUISHED_VALUE;
WRITE_UNALIGNED(dbg, (void *) arange_ptr,
(const void *) &x,
sizeof(x), extension_word_size);
arange_ptr += extension_word_size;
}
adjusted_length = arange_num_bytes - uword_size
- extension_word_size;
{
Dwarf_Unsigned du = adjusted_length;
WRITE_UNALIGNED(dbg, (void *) arange_ptr,
(const void *) &du, sizeof(du), uword_size);
arange_ptr += uword_size;
}
{
Dwarf_Half verstamp = CURRENT_VERSION_STAMP;
WRITE_UNALIGNED(dbg, (void *) arange_ptr,
(const void *) &verstamp,
sizeof(verstamp), sizeof(Dwarf_Half));
arange_ptr += sizeof(Dwarf_Half);
}
WRITE_UNALIGNED(dbg, (void *) arange_ptr,
(const void *) &big_zero,
sizeof(big_zero), uword_size);
arange_ptr += uword_size;
{
unsigned long count = dbg->de_arange_count + 1;
int res;
if (dbg->de_reloc_pair) {
count = (3 * dbg->de_arange_count) + 1;
}
res = _dwarf_pro_pre_alloc_n_reloc_slots(dbg,
DEBUG_ARANGES, count);
if (res != DW_DLV_OK) {
{
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return (0);
}
}
}
res = dbg->de_reloc_name(dbg,
DEBUG_ARANGES,
extension_word_size +
uword_size + sizeof(Dwarf_Half),
dbg->de_sect_name_idx[DEBUG_INFO],
dwarf_drt_data_reloc, uword_size);
*arange_ptr = dbg->de_pointer_size;
arange_ptr++;
*arange_ptr = 0;
arange_ptr++;
if (remainder != 0)
arange_ptr += (2 * upointer_size) - remainder;
for (given_arange = dbg->de_arange; given_arange != NULL;
given_arange = given_arange->ag_next) {
res = dbg->de_reloc_name(dbg, DEBUG_ARANGES, arange_ptr - arange,
(long) given_arange->ag_symbol_index,
dwarf_drt_data_reloc, upointer_size);
if (res != DW_DLV_OK) {
{
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return (0);
}
}
WRITE_UNALIGNED(dbg, (void *) arange_ptr,
(const void *) &given_arange->ag_begin_address,
sizeof(given_arange->ag_begin_address),
upointer_size);
arange_ptr += upointer_size;
if (dbg->de_reloc_pair &&
given_arange->ag_end_symbol_index != 0 &&
given_arange->ag_length == 0) {
Dwarf_Unsigned val;
res = dbg->de_reloc_pair(dbg, DEBUG_ARANGES, arange_ptr - arange,
given_arange->ag_symbol_index,
given_arange->ag_end_symbol_index,
dwarf_drt_first_of_length_pair,
upointer_size);
if (res != DW_DLV_OK) {
{
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return (0);
}
}
val = given_arange->ag_end_symbol_offset -
given_arange->ag_begin_address;
WRITE_UNALIGNED(dbg, (void *) arange_ptr,
(const void *) &val,
sizeof(val), upointer_size);
arange_ptr += upointer_size;
} else {
WRITE_UNALIGNED(dbg, (void *) arange_ptr,
(const void *) &given_arange->ag_length,
sizeof(given_arange->ag_length),
upointer_size);
arange_ptr += upointer_size;
}
}
WRITE_UNALIGNED(dbg, (void *) arange_ptr,
(const void *) &big_zero,
sizeof(big_zero), upointer_size);
arange_ptr += upointer_size;
WRITE_UNALIGNED(dbg, (void *) arange_ptr,
(const void *) &big_zero,
sizeof(big_zero), upointer_size);
return (int) dbg->de_n_debug_sect;
}