#include "config.h"
#include "libdwarfdefs.h"
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include "pro_incl.h"
#include <stddef.h>
#include "dwarf.h"
#include "libdwarf.h"
#include "pro_opaque.h"
#include "pro_error.h"
#include "pro_encode_nm.h"
#include "pro_alloc.h"
#include "pro_die.h"
#include "pro_expr.h"
#ifndef R_MIPS_NONE
#define R_MIPS_NONE 0
#endif
#define NO_ELF_SYM_INDEX 0
#ifdef WORDS_BIGENDIAN
#define ASNAR(t,s,l) \
do
{ \
unsigned tbyte =
sizeof
(t) - l; \
t = 0; \
dbg->de_copy_word(((
char
*)&t)+tbyte ,&s[0],l);\
}
while
(0)
#else /* LITTLE ENDIAN */
#define ASNAR(t,s,l) \
do
{ \
t = 0; \
dbg->de_copy_word(&t,&s[0],l); \
}
while
(0)
#endif /* end LITTLE- BIG-ENDIAN */
#ifdef WORDS_BIGENDIAN
#define ASNOUT(t,s,l) \
do
{ \
unsigned sbyte = 0; \
char
*p = 0; \
if
(l >
sizeof
(s)) { \
_dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);\
return
DW_DLV_ERROR; \
} \
sbyte =
sizeof
(s) - l; \
p = (
const
char
*)(&s); \
dbg->de_copy_word(t,(
const
void
*)(p+sbyte),l);\
}
while
(0)
#else /* LITTLEENDIAN */
#define ASNOUT(t,s,l) \
do
{ \
const
char
*p = 0; \
if
(l >
sizeof
(s)) { \
_dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);\
return
DW_DLV_ERROR; \
} \
p = (
const
char
*)(&s); \
memcpy
(t,(
const
void
*)p,l); \
dbg->de_copy_word(t,(
const
void
*)p,l); \
}
while
(0)
#endif /* ENDIANNESS */
#ifdef WORDS_BIGENDIAN
#define SIGN_EXTEND(dest, length) \
do
{ \
if
(*(Dwarf_Sbyte *)((
char
*)&dest + \
sizeof
(dest) - length) < 0) { \
memcpy
((
char
*)&dest,
"\xff\xff\xff\xff\xff\xff\xff\xff"
,\
sizeof
(dest) - length); \
} \
}
while
(0)
#else /* LITTLE ENDIAN */
#define SIGN_EXTEND(dest, length) \
do
{ \
if
(*(Dwarf_Sbyte *)((
char
*)&dest + (length-1)) < 0) { \
memcpy
((
char
*)&dest+length, \
"\xff\xff\xff\xff\xff\xff\xff\xff"
, \
sizeof
(dest) - length); \
} \
}
while
(0)
#endif /* ! LITTLE_ENDIAN */
static
int
local_add_AT_address_a(Dwarf_P_Debug dbg,
Dwarf_P_Die ownerdie,
Dwarf_Half attr,
Dwarf_Signed form,
Dwarf_Unsigned pc_value,
Dwarf_Unsigned sym_index,
Dwarf_P_Attribute *attr_out,
Dwarf_Error * error);
Dwarf_P_Attribute
dwarf_add_AT_targ_address(Dwarf_P_Debug dbg,
Dwarf_P_Die ownerdie,
Dwarf_Half attr,
Dwarf_Unsigned pc_value,
Dwarf_Signed sym_index, Dwarf_Error * error)
{
Dwarf_P_Attribute a = 0;
int
res = 0;
if
(sym_index < 0) {
return
((Dwarf_P_Attribute) DW_DLV_BADADDR);
}
res = dwarf_add_AT_targ_address_c(dbg,
ownerdie, attr, pc_value,
(Dwarf_Unsigned) sym_index,
&a,
error);
if
(res != DW_DLV_OK) {
return
((Dwarf_P_Attribute) DW_DLV_BADADDR);
}
return
a;
}
Dwarf_P_Attribute
dwarf_add_AT_targ_address_b(Dwarf_P_Debug dbg,
Dwarf_P_Die ownerdie,
Dwarf_Half attr,
Dwarf_Unsigned pc_value,
Dwarf_Unsigned sym_index,
Dwarf_Error * error)
{
Dwarf_P_Attribute a = 0;
int
res = 0;
res = dwarf_add_AT_targ_address_c(dbg,
ownerdie,attr,pc_value,sym_index,
&a, error);
if
(res != DW_DLV_OK) {
return
((Dwarf_P_Attribute) DW_DLV_BADADDR);
}
return
a;
}
int
dwarf_add_AT_targ_address_c(Dwarf_P_Debug dbg,
Dwarf_P_Die ownerdie,
Dwarf_Half attr,
Dwarf_Unsigned pc_value,
Dwarf_Unsigned sym_index,
Dwarf_P_Attribute *attr_out,
Dwarf_Error * error)
{
int
res = 0;
switch
(attr) {
case
DW_AT_low_pc:
case
DW_AT_high_pc:
case
DW_AT_location:
case
DW_AT_string_length:
case
DW_AT_return_addr:
case
DW_AT_frame_base:
case
DW_AT_segment:
case
DW_AT_static_link:
case
DW_AT_use_location:
case
DW_AT_vtable_elem_location:
case
DW_AT_const_value:
case
DW_AT_entry_pc:
break
;
default
:
if
(attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
_dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
return
DW_DLV_ERROR;
}
break
;
}
res = local_add_AT_address_a(dbg, ownerdie, attr, DW_FORM_addr,
pc_value, sym_index,attr_out, error);
return
res;
}
Dwarf_P_Attribute
dwarf_add_AT_ref_address(Dwarf_P_Debug dbg,
Dwarf_P_Die ownerdie,
Dwarf_Half attr,
Dwarf_Unsigned pc_value,
Dwarf_Unsigned sym_index,
Dwarf_Error * error)
{
Dwarf_P_Attribute a = 0;
int
res = 0;
res = dwarf_add_AT_ref_address_a(dbg,ownerdie,
attr,pc_value,sym_index,&a,error);
if
(res != DW_DLV_OK) {
return
((Dwarf_P_Attribute) DW_DLV_BADADDR);
}
return
a;
}
int
dwarf_add_AT_ref_address_a(Dwarf_P_Debug dbg,
Dwarf_P_Die ownerdie,
Dwarf_Half attr,
Dwarf_Unsigned pc_value,
Dwarf_Unsigned sym_index,
Dwarf_P_Attribute *attr_out,
Dwarf_Error * error)
{
int
res = 0;
switch
(attr) {
case
DW_AT_type:
case
DW_AT_import:
break
;
default
:
if
(attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
_dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
return
DW_DLV_ERROR;
}
break
;
}
res = local_add_AT_address_a(dbg, ownerdie,
attr, DW_FORM_ref_addr,
pc_value, sym_index,attr_out, error);
return
res;
}
static
int
local_add_AT_address_a(Dwarf_P_Debug dbg,
Dwarf_P_Die ownerdie,
Dwarf_Half attr,
Dwarf_Signed form,
Dwarf_Unsigned pc_value,
Dwarf_Unsigned sym_index,
Dwarf_P_Attribute *attr_out,
Dwarf_Error * error)
{
Dwarf_P_Attribute new_attr;
int
upointer_size = 0;
if
(dbg == NULL) {
_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
return
DW_DLV_ERROR;
}
upointer_size = dbg->de_pointer_size;
if
(ownerdie == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
return
DW_DLV_ERROR;
}
new_attr = (Dwarf_P_Attribute)
_dwarf_p_get_alloc(dbg,
sizeof
(
struct
Dwarf_P_Attribute_s));
if
(new_attr == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
new_attr->ar_attribute = attr;
new_attr->ar_attribute_form = form;
new_attr->ar_nbytes = upointer_size;
new_attr->ar_rel_symidx = sym_index;
new_attr->ar_reloc_len = upointer_size;
new_attr->ar_next = 0;
if
(sym_index != NO_ELF_SYM_INDEX) {
new_attr->ar_rel_type = dbg->de_ptr_reloc;
}
else
{
new_attr->ar_rel_type = R_MIPS_NONE;
}
new_attr->ar_data = (
char
*)
_dwarf_p_get_alloc(dbg, upointer_size);
if
(new_attr->ar_data == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
WRITE_UNALIGNED(dbg, new_attr->ar_data,
(
const
void
*) &pc_value,
sizeof
(pc_value), upointer_size);
_dwarf_pro_add_at_to_die(ownerdie, new_attr);
*attr_out = new_attr;
return
DW_DLV_OK;
}
int
dwarf_compress_integer_block_a(
Dwarf_P_Debug dbg,
Dwarf_Unsigned input_array_length,
Dwarf_Signed * input_array,
Dwarf_Unsigned *output_block_len,
void
** output_block_returned,
Dwarf_Error* error
)
{
Dwarf_Unsigned output_length_in_bytes = 0;
char
* output_block = 0;
char
encode_buffer[ENCODE_SPACE_NEEDED];
unsigned u = 0;
char
* ptr = 0;
int
remain = 0;
int
result = 0;
if
(dbg == NULL) {
_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
return
DW_DLV_ERROR;
}
output_length_in_bytes = 0;
for
(u=0; u<input_array_length; u++) {
int
unit_encoded_size;
Dwarf_Signed unit = 0;
unit = input_array[u];
result = _dwarf_pro_encode_signed_leb128_nm(
unit, &unit_encoded_size,
encode_buffer,
sizeof
(encode_buffer));
if
(result != DW_DLV_OK) {
_dwarf_p_error(NULL, error, DW_DLE_LEB_IMPROPER);
return
DW_DLV_ERROR;
}
output_length_in_bytes += unit_encoded_size;
}
output_block = (
void
*)
_dwarf_p_get_alloc(dbg, output_length_in_bytes);
if
(output_block == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
ptr = output_block;
remain = output_length_in_bytes;
for
(u=0; u<input_array_length; u++) {
int
unit_encoded_size;
Dwarf_Signed unit = 0;
unit = input_array[u];
result = _dwarf_pro_encode_signed_leb128_nm(unit,
&unit_encoded_size,
ptr, remain);
if
(result != DW_DLV_OK) {
_dwarf_p_error(NULL, error, DW_DLE_LEB_IMPROPER);
return
DW_DLV_ERROR;
}
remain -= unit_encoded_size;
ptr += unit_encoded_size;
}
*output_block_len = output_length_in_bytes;
*output_block_returned = output_block;
return
DW_DLV_OK;
}
void
*
dwarf_compress_integer_block(
Dwarf_P_Debug dbg,
Dwarf_Bool unit_is_signed,
Dwarf_Small unit_length_in_bits,
void
* input_block,
Dwarf_Unsigned input_length_in_units,
Dwarf_Unsigned* output_length_in_bytes_ptr,
Dwarf_Error* error
)
{
Dwarf_Unsigned output_length_in_bytes = 0;
char
* output_block = 0;
char
encode_buffer[ENCODE_SPACE_NEEDED];
unsigned u = 0;
char
* ptr = 0;
int
remain = 0;
int
result = 0;
char
*inptr = 0;
if
(dbg == NULL) {
_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
return
((
void
*)DW_DLV_BADADDR);
}
if
(unit_is_signed ==
false
||
unit_length_in_bits != 32 ||
input_block == NULL ||
input_length_in_units == 0 ||
output_length_in_bytes_ptr == NULL) {
_dwarf_p_error(NULL, error, DW_DLE_BADBITC);
return
((
void
*) DW_DLV_BADADDR);
}
output_length_in_bytes = 0;
inptr = input_block;
for
(u=0; u<input_length_in_units; u++) {
int
unit_encoded_size;
Dwarf_Signed unit = 0;
ASNAR(unit,inptr,DWARF_32BIT_SIZE);
SIGN_EXTEND(unit,DWARF_32BIT_SIZE);
result = _dwarf_pro_encode_signed_leb128_nm(
unit, &unit_encoded_size,
encode_buffer,
sizeof
(encode_buffer));
if
(result != DW_DLV_OK) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
((Dwarf_P_Attribute)DW_DLV_BADADDR);
}
output_length_in_bytes += unit_encoded_size;
inptr += DWARF_32BIT_SIZE;
}
output_block = (
void
*)
_dwarf_p_get_alloc(dbg, output_length_in_bytes);
if
(output_block == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
((
void
*)DW_DLV_BADADDR);
}
ptr = output_block;
inptr = input_block;
remain = output_length_in_bytes;
for
(u=0; u<input_length_in_units; u++) {
int
unit_encoded_size;
Dwarf_Signed unit = 0;
ASNAR(unit,inptr,DWARF_32BIT_SIZE);
SIGN_EXTEND(unit,DWARF_32BIT_SIZE);
result = _dwarf_pro_encode_signed_leb128_nm(unit,
&unit_encoded_size,
ptr, remain);
if
(result != DW_DLV_OK) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
((Dwarf_P_Attribute)DW_DLV_BADADDR);
}
remain -= unit_encoded_size;
ptr += unit_encoded_size;
inptr += DWARF_32BIT_SIZE;
}
if
(remain != 0) {
_dwarf_p_dealloc(dbg, (unsigned
char
*)output_block);
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
((Dwarf_P_Attribute)DW_DLV_BADADDR);
}
*output_length_in_bytes_ptr = output_length_in_bytes;
return
(
void
*) output_block;
}
void
dwarf_dealloc_compressed_block(Dwarf_P_Debug dbg,
void
* space)
{
_dwarf_p_dealloc(dbg, space);
}
int
dwarf_add_AT_dataref_a(
Dwarf_P_Debug dbg,
Dwarf_P_Die ownerdie,
Dwarf_Half attr,
Dwarf_Unsigned pc_value,
Dwarf_Unsigned sym_index,
Dwarf_P_Attribute *attr_out,
Dwarf_Error * error)
{
int
res = 0;
res = local_add_AT_address_a(dbg, ownerdie, attr,
dbg->de_ar_data_attribute_form,
pc_value,
sym_index,
attr_out,
error);
return
res;
}
Dwarf_P_Attribute
dwarf_add_AT_dataref(
Dwarf_P_Debug dbg,
Dwarf_P_Die ownerdie,
Dwarf_Half attr,
Dwarf_Unsigned pc_value,
Dwarf_Unsigned sym_index,
Dwarf_Error * error)
{
Dwarf_P_Attribute a = 0;
int
res = 0;
res = local_add_AT_address_a(dbg, ownerdie, attr,
dbg->de_ar_data_attribute_form,
pc_value,
sym_index,
&a,
error);
if
(res != DW_DLV_OK) {
return
((Dwarf_P_Attribute)DW_DLV_BADADDR);
}
return
a;
}
Dwarf_P_Attribute
dwarf_add_AT_block(
Dwarf_P_Debug dbg,
Dwarf_P_Die ownerdie,
Dwarf_Half attr,
Dwarf_Small *block_data,
Dwarf_Unsigned block_size,
Dwarf_Error *error)
{
int
res = 0;
Dwarf_P_Attribute new_attr = 0;
res = dwarf_add_AT_block_a(dbg,ownerdie,attr,
block_data,block_size,&new_attr,error);
if
(res != DW_DLV_OK) {
return
((Dwarf_P_Attribute)DW_DLV_BADADDR);
}
return
new_attr;
}
int
dwarf_add_AT_block_a(
Dwarf_P_Debug dbg,
Dwarf_P_Die ownerdie,
Dwarf_Half attr,
Dwarf_Small *block_data,
Dwarf_Unsigned block_size,
Dwarf_P_Attribute* attr_out,
Dwarf_Error *error)
{
Dwarf_P_Attribute new_attr = 0;
int
result = 0;
char
encode_buffer[ENCODE_SPACE_NEEDED];
int
len_size = 0;
char
* attrdata = 0;
if
(dbg == NULL) {
_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
return
DW_DLV_ERROR;
}
if
(ownerdie == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
return
DW_DLV_ERROR;
}
result = _dwarf_pro_encode_leb128_nm(block_size, &len_size,
encode_buffer,
sizeof
(encode_buffer));
if
(result != DW_DLV_OK) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
new_attr = (Dwarf_P_Attribute)
_dwarf_p_get_alloc(dbg,
sizeof
(
struct
Dwarf_P_Attribute_s));
if
(new_attr == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
new_attr->ar_attribute = attr;
new_attr->ar_attribute_form = DW_FORM_block;
new_attr->ar_nbytes = len_size + block_size;
new_attr->ar_next = 0;
new_attr->ar_data = attrdata = (
char
*)
_dwarf_p_get_alloc(dbg, len_size + block_size);
if
(new_attr->ar_data == NULL) {
_dwarf_p_dealloc(dbg, (unsigned
char
*) new_attr);
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
memcpy
(attrdata, encode_buffer, len_size);
attrdata += len_size;
memcpy
(attrdata, block_data, block_size);
_dwarf_pro_add_at_to_die(ownerdie, new_attr);
*attr_out = new_attr;
return
DW_DLV_OK;
}
Dwarf_P_Attribute
dwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg,
Dwarf_P_Die ownerdie,
Dwarf_Half attr,
Dwarf_Unsigned value, Dwarf_Error * error)
{
Dwarf_P_Attribute a = 0;
int
res = 0;
res = dwarf_add_AT_unsigned_const_a(dbg,
ownerdie,attr,value,
&a,error);
if
(res != DW_DLV_OK) {
return
((Dwarf_P_Attribute) DW_DLV_BADADDR);
}
return
a;
}
int
dwarf_add_AT_unsigned_const_a(Dwarf_P_Debug dbg,
Dwarf_P_Die ownerdie,
Dwarf_Half attr,
Dwarf_Unsigned value,
Dwarf_P_Attribute *attr_out,
Dwarf_Error * error)
{
Dwarf_P_Attribute new_attr = 0;
Dwarf_Half attr_form = 0;
Dwarf_Small size = 0;
if
(dbg == NULL) {
_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
return
DW_DLV_ERROR;
}
if
(ownerdie == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
return
DW_DLV_ERROR;
}
switch
(attr) {
case
DW_AT_ordering:
case
DW_AT_byte_size:
case
DW_AT_bit_offset:
case
DW_AT_bit_size:
case
DW_AT_inline:
case
DW_AT_language:
case
DW_AT_visibility:
case
DW_AT_virtuality:
case
DW_AT_accessibility:
case
DW_AT_address_class:
case
DW_AT_calling_convention:
case
DW_AT_encoding:
case
DW_AT_identifier_case:
case
DW_AT_MIPS_loop_unroll_factor:
case
DW_AT_MIPS_software_pipeline_depth:
break
;
case
DW_AT_decl_column:
case
DW_AT_decl_file:
case
DW_AT_decl_line:
case
DW_AT_const_value:
case
DW_AT_start_scope:
case
DW_AT_stride_size:
case
DW_AT_count:
case
DW_AT_high_pc:
case
DW_AT_associated:
case
DW_AT_allocated:
case
DW_AT_upper_bound:
case
DW_AT_lower_bound:
case
DW_AT_call_file:
case
DW_AT_call_line:
case
DW_AT_data_member_location:
case
DW_AT_trampoline:
break
;
default
:
if
(attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
_dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
return
DW_DLV_ERROR;
}
break
;
}
if
(value <= UCHAR_MAX) {
attr_form = DW_FORM_data1;
size = 1;
}
else
if
(value <= USHRT_MAX) {
attr_form = DW_FORM_data2;
size = 2;
}
else
if
(value <= UINT_MAX) {
attr_form = DW_FORM_data4;
size = 4;
}
else
{
attr_form = DW_FORM_data8;
size = 8;
}
new_attr = (Dwarf_P_Attribute)
_dwarf_p_get_alloc(dbg,
sizeof
(
struct
Dwarf_P_Attribute_s));
if
(new_attr == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
new_attr->ar_attribute = attr;
new_attr->ar_attribute_form = attr_form;
new_attr->ar_rel_type = R_MIPS_NONE;
new_attr->ar_reloc_len = 0;
new_attr->ar_nbytes = size;
new_attr->ar_next = 0;
new_attr->ar_data = (
char
*)
_dwarf_p_get_alloc(dbg, size);
if
(new_attr->ar_data == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
WRITE_UNALIGNED(dbg, new_attr->ar_data,
(
const
void
*) &value,
sizeof
(value), size);
_dwarf_pro_add_at_to_die(ownerdie, new_attr);
*attr_out = new_attr;
return
DW_DLV_OK;
}
Dwarf_P_Attribute
dwarf_add_AT_signed_const(Dwarf_P_Debug dbg,
Dwarf_P_Die ownerdie,
Dwarf_Half attr,
Dwarf_Signed value,
Dwarf_Error * error)
{
Dwarf_P_Attribute a = 0;
int
res = 0;
res = dwarf_add_AT_signed_const_a(dbg,
ownerdie,attr,value,&a,error);
if
(res != DW_DLV_OK) {
return
((Dwarf_P_Attribute) DW_DLV_BADADDR);
}
return
a;
}
int
dwarf_add_AT_signed_const_a(Dwarf_P_Debug dbg,
Dwarf_P_Die ownerdie,
Dwarf_Half attr,
Dwarf_Signed value,
Dwarf_P_Attribute *attr_out,
Dwarf_Error * error)
{
Dwarf_P_Attribute new_attr = 0;
Dwarf_Half attr_form = 0;
Dwarf_Small size = 0;
if
(dbg == NULL) {
_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
return
DW_DLV_ERROR;
}
if
(ownerdie == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
return
DW_DLV_ERROR;
}
switch
(attr) {
case
DW_AT_lower_bound:
case
DW_AT_upper_bound:
case
DW_AT_const_value:
case
DW_AT_bit_offset:
case
DW_AT_bit_size:
case
DW_AT_byte_size:
case
DW_AT_count:
case
DW_AT_byte_stride:
case
DW_AT_bit_stride:
case
DW_AT_allocated:
case
DW_AT_associated:
break
;
default
:
if
(attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
_dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
return
DW_DLV_ERROR;
}
break
;
}
if
(value >= SCHAR_MIN && value <= SCHAR_MAX) {
attr_form = DW_FORM_data1;
size = 1;
}
else
if
(value >= SHRT_MIN && value <= SHRT_MAX) {
attr_form = DW_FORM_data2;
size = 2;
}
else
if
(value >= INT_MIN && value <= INT_MAX) {
attr_form = DW_FORM_data4;
size = 4;
}
else
{
attr_form = DW_FORM_data8;
size = 8;
}
new_attr = (Dwarf_P_Attribute)
_dwarf_p_get_alloc(dbg,
sizeof
(
struct
Dwarf_P_Attribute_s));
if
(new_attr == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
new_attr->ar_attribute = attr;
new_attr->ar_attribute_form = attr_form;
new_attr->ar_rel_type = R_MIPS_NONE;
new_attr->ar_reloc_len = 0;
new_attr->ar_nbytes = size;
new_attr->ar_next = 0;
new_attr->ar_data = (
char
*)
_dwarf_p_get_alloc(dbg, size);
if
(new_attr->ar_data == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
WRITE_UNALIGNED(dbg, new_attr->ar_data,
(
const
void
*) &value,
sizeof
(value), size);
_dwarf_pro_add_at_to_die(ownerdie, new_attr);
*attr_out = new_attr;
return
DW_DLV_OK;
}
Dwarf_P_Attribute
dwarf_add_AT_location_expr(Dwarf_P_Debug dbg,
Dwarf_P_Die ownerdie,
Dwarf_Half attr,
Dwarf_P_Expr loc_expr, Dwarf_Error * error)
{
int
res = 0;
Dwarf_P_Attribute a = 0;
res = dwarf_add_AT_location_expr_a(dbg,ownerdie,attr,
loc_expr,&a,error);
if
(res != DW_DLV_OK) {
return
((Dwarf_P_Attribute) DW_DLV_BADADDR);
}
return
a;
}
int
dwarf_add_AT_location_expr_a(Dwarf_P_Debug dbg,
Dwarf_P_Die ownerdie,
Dwarf_Half attr,
Dwarf_P_Expr loc_expr,
Dwarf_P_Attribute *attr_out,
Dwarf_Error * error)
{
char
encode_buffer[ENCODE_SPACE_NEEDED];
int
res = 0;
Dwarf_P_Attribute new_attr = 0;
Dwarf_Half attr_form = 0;
char
*len_str = 0;
int
len_size = 0;
Dwarf_Unsigned block_size = 0;
char
*block_dest_ptr = 0;
int
do_len_as_int = 0;
if
(dbg == NULL) {
_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
return
DW_DLV_ERROR;
}
if
(ownerdie == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
return
DW_DLV_ERROR;
}
if
(loc_expr == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_EXPR_NULL);
return
DW_DLV_ERROR;
}
if
(loc_expr->ex_dbg != dbg) {
_dwarf_p_error(dbg, error, DW_DLE_LOC_EXPR_BAD);
return
DW_DLV_ERROR;
}
block_size = loc_expr->ex_next_byte_offset;
switch
(attr) {
case
DW_AT_location:
case
DW_AT_string_length:
case
DW_AT_const_value:
case
DW_AT_use_location:
case
DW_AT_return_addr:
case
DW_AT_data_member_location:
case
DW_AT_frame_base:
case
DW_AT_static_link:
case
DW_AT_vtable_elem_location:
case
DW_AT_lower_bound:
case
DW_AT_upper_bound:
case
DW_AT_count:
case
DW_AT_associated:
case
DW_AT_allocated:
case
DW_AT_data_location:
case
DW_AT_byte_stride:
case
DW_AT_bit_stride:
case
DW_AT_byte_size:
case
DW_AT_bit_size:
break
;
default
:
if
(attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
_dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
return
DW_DLV_ERROR;
}
break
;
}
if
(block_size <= UCHAR_MAX) {
attr_form = DW_FORM_block1;
len_size = 1;
do_len_as_int = 1;
}
else
if
(block_size <= USHRT_MAX) {
attr_form = DW_FORM_block2;
len_size = 2;
do_len_as_int = 1;
}
else
if
(block_size <= UINT_MAX) {
attr_form = DW_FORM_block4;
len_size = 4;
do_len_as_int = 1;
}
else
{
attr_form = DW_FORM_block;
res = _dwarf_pro_encode_leb128_nm(block_size, &len_size,
encode_buffer,
sizeof
(encode_buffer));
if
(res != DW_DLV_OK) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
len_str = (
char
*) encode_buffer;
}
new_attr = (Dwarf_P_Attribute)
_dwarf_p_get_alloc(dbg,
sizeof
(
struct
Dwarf_P_Attribute_s));
if
(new_attr == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
new_attr->ar_attribute = attr;
new_attr->ar_attribute_form = attr_form;
new_attr->ar_reloc_len = dbg->de_pointer_size;
if
(loc_expr->ex_reloc_sym_index != NO_ELF_SYM_INDEX) {
new_attr->ar_rel_type = dbg->de_ptr_reloc;
}
else
{
new_attr->ar_rel_type = R_MIPS_NONE;
}
new_attr->ar_rel_symidx = loc_expr->ex_reloc_sym_index;
new_attr->ar_rel_offset =
loc_expr->ex_reloc_offset + len_size;
new_attr->ar_nbytes = block_size + len_size;
new_attr->ar_next = 0;
new_attr->ar_data = block_dest_ptr =
(
char
*) _dwarf_p_get_alloc(dbg, block_size + len_size);
if
(new_attr->ar_data == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
if
(do_len_as_int) {
WRITE_UNALIGNED(dbg, block_dest_ptr, (
const
void
*) &block_size,
sizeof
(block_size), len_size);
}
else
{
memcpy
(block_dest_ptr, len_str, len_size);
}
block_dest_ptr += len_size;
if
(block_size >
sizeof
(loc_expr->ex_byte_stream)) {
_dwarf_p_error(dbg, error, DW_DLE_EXPR_LENGTH_BAD);
return
DW_DLV_ERROR;
}
memcpy
(block_dest_ptr, &(loc_expr->ex_byte_stream[0]), block_size);
_dwarf_pro_add_at_to_die(ownerdie, new_attr);
*attr_out = new_attr;
return
DW_DLV_OK;
}
static
int
_dwarf_add_AT_reference_internal_a(Dwarf_P_Debug dbg,
Dwarf_P_Die ownerdie,
Dwarf_Half attr,
Dwarf_P_Die otherdie,
int
check_otherdie,
Dwarf_P_Attribute *attr_out,
Dwarf_Error * error)
{
Dwarf_P_Attribute new_attr = 0;
if
(dbg == NULL) {
_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
return
DW_DLV_ERROR;
}
if
(ownerdie == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
return
DW_DLV_ERROR;
}
if
(check_otherdie && (otherdie == NULL)) {
_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
return
DW_DLV_ERROR;
}
switch
(attr) {
case
DW_AT_count:
case
DW_AT_sibling:
case
DW_AT_byte_size:
case
DW_AT_bit_offset:
case
DW_AT_bit_size:
case
DW_AT_discr:
case
DW_AT_import:
case
DW_AT_common_reference:
case
DW_AT_containing_type:
case
DW_AT_default_value:
case
DW_AT_lower_bound:
case
DW_AT_bit_stride:
case
DW_AT_upper_bound:
case
DW_AT_abstract_origin:
case
DW_AT_base_types:
case
DW_AT_friend:
case
DW_AT_namelist_item:
case
DW_AT_priority:
case
DW_AT_specification:
case
DW_AT_type:
case
DW_AT_allocated:
case
DW_AT_associated:
case
DW_AT_byte_stride:
case
DW_AT_extension:
case
DW_AT_trampoline:
case
DW_AT_small:
case
DW_AT_object_pointer:
case
DW_AT_signature:
break
;
default
:
if
(attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
_dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
return
DW_DLV_ERROR;
}
break
;
}
new_attr = (Dwarf_P_Attribute)
_dwarf_p_get_alloc(dbg,
sizeof
(
struct
Dwarf_P_Attribute_s));
if
(new_attr == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
new_attr->ar_attribute = attr;
new_attr->ar_attribute_form = dbg->de_ar_ref_attr_form;
new_attr->ar_nbytes = dbg->de_dwarf_offset_size;
new_attr->ar_reloc_len = dbg->de_dwarf_offset_size;
new_attr->ar_ref_die = otherdie;
new_attr->ar_rel_type = R_MIPS_NONE;
new_attr->ar_next = 0;
_dwarf_pro_add_at_to_die(ownerdie, new_attr);
*attr_out = new_attr;
return
DW_DLV_OK;
}
int
dwarf_add_AT_reference_c(Dwarf_P_Debug dbg,
Dwarf_P_Die ownerdie,
Dwarf_Half attr,
Dwarf_P_Die otherdie,
Dwarf_P_Attribute *attr_out,
Dwarf_Error * error)
{
int
res = 0;
res = _dwarf_add_AT_reference_internal_a(dbg,
ownerdie,
attr,
otherdie,
0,
attr_out,
error);
return
res;
}
Dwarf_P_Attribute
dwarf_add_AT_reference(Dwarf_P_Debug dbg,
Dwarf_P_Die ownerdie,
Dwarf_Half attr,
Dwarf_P_Die otherdie, Dwarf_Error * error)
{
Dwarf_P_Attribute a = 0;
int
res = 0;
res = _dwarf_add_AT_reference_internal_a(dbg,
ownerdie,
attr,
otherdie,
1,
&a,
error);
if
(res != DW_DLV_OK) {
return
(Dwarf_P_Attribute)DW_DLV_BADADDR;
}
return
a;
}
Dwarf_P_Attribute
dwarf_add_AT_reference_b(Dwarf_P_Debug dbg,
Dwarf_P_Die ownerdie,
Dwarf_Half attr,
Dwarf_P_Die otherdie,
Dwarf_Error * error)
{
Dwarf_P_Attribute a = 0;
int
res = 0;
res = _dwarf_add_AT_reference_internal_a(dbg,
ownerdie,
attr,
otherdie,
0,
&a,
error);
if
(res != DW_DLV_OK) {
return
(Dwarf_P_Attribute)DW_DLV_BADADDR;
}
return
a;
}
int
dwarf_fixup_AT_reference_die(Dwarf_P_Debug dbg,
Dwarf_Half attrnum,
Dwarf_P_Die sourcedie,
Dwarf_P_Die targetdie,
Dwarf_Error *error)
{
Dwarf_P_Attribute a = 0;
Dwarf_P_Attribute cur = 0;
if
(dbg == NULL) {
_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
return
DW_DLV_ERROR;
}
for
(cur = sourcedie->di_attrs; cur; cur = cur->ar_next) {
if
(attrnum == cur->ar_attribute) {
a = cur;
break
;
}
}
if
(!a) {
_dwarf_p_error(dbg, error, DW_DLE_AT_FIXUP_NULL);
return
DW_DLV_ERROR;
}
if
(a->ar_ref_die) {
_dwarf_p_error(dbg, error, DW_DLE_AT_FIXUP_DUP);
return
DW_DLV_ERROR;
}
a->ar_ref_die = targetdie;
return
DW_DLV_OK;
}
Dwarf_P_Attribute
dwarf_add_AT_flag(Dwarf_P_Debug dbg,
Dwarf_P_Die ownerdie,
Dwarf_Half attr,
Dwarf_Small flag,
Dwarf_Error * error)
{
Dwarf_P_Attribute a = 0;
int
res = 0;
res = dwarf_add_AT_flag_a(dbg,ownerdie,attr,flag,
&a,error);
if
(res != DW_DLV_OK) {
return
((Dwarf_P_Attribute) DW_DLV_BADADDR);
}
return
a;
}
int
dwarf_add_AT_flag_a(Dwarf_P_Debug dbg,
Dwarf_P_Die ownerdie,
Dwarf_Half attr,
Dwarf_Small flag,
Dwarf_P_Attribute * attr_out,
Dwarf_Error * error)
{
Dwarf_P_Attribute new_attr = 0;
if
(dbg == NULL) {
_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
return
DW_DLV_ERROR;
}
if
(ownerdie == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
return
DW_DLV_ERROR;
}
new_attr = (Dwarf_P_Attribute)
_dwarf_p_get_alloc(dbg,
sizeof
(
struct
Dwarf_P_Attribute_s));
if
(new_attr == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
new_attr->ar_attribute = attr;
new_attr->ar_attribute_form = DW_FORM_flag;
new_attr->ar_nbytes = 1;
new_attr->ar_reloc_len = 0;
new_attr->ar_rel_type = R_MIPS_NONE;
new_attr->ar_next = 0;
new_attr->ar_data = (
char
*)
_dwarf_p_get_alloc(dbg, 1);
if
(new_attr->ar_data == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
memcpy
(new_attr->ar_data, &flag, 1);
_dwarf_pro_add_at_to_die(ownerdie, new_attr);
*attr_out = new_attr;
return
DW_DLV_OK;
}
Dwarf_P_Attribute
dwarf_add_AT_string(Dwarf_P_Debug dbg,
Dwarf_P_Die ownerdie,
Dwarf_Half attr,
char
*string, Dwarf_Error * error)
{
Dwarf_P_Attribute a = 0;
int
res = 0;
res = dwarf_add_AT_string_a(dbg,
ownerdie,attr,string,&a,error);
if
(res != DW_DLV_OK) {
return
((Dwarf_P_Attribute) DW_DLV_BADADDR);
}
return
a;
}
int
dwarf_add_AT_string_a(Dwarf_P_Debug dbg,
Dwarf_P_Die ownerdie,
Dwarf_Half attr,
char
*string,
Dwarf_P_Attribute *attr_out,
Dwarf_Error * error)
{
Dwarf_P_Attribute new_attr = 0;
int
res = 0;
if
(dbg == NULL) {
_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
return
DW_DLV_ERROR;
}
if
(ownerdie == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
return
DW_DLV_ERROR;
}
new_attr = (Dwarf_P_Attribute)
_dwarf_p_get_alloc(dbg,
sizeof
(
struct
Dwarf_P_Attribute_s));
if
(new_attr == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
switch
(attr) {
case
DW_AT_comp_dir:
case
DW_AT_const_value:
case
DW_AT_linkage_name:
case
DW_AT_MIPS_abstract_name:
case
DW_AT_MIPS_linkage_name:
case
DW_AT_name:
case
DW_AT_producer:
break
;
default
:
if
(attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
_dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
return
DW_DLV_ERROR;
}
break
;
}
new_attr->ar_attribute = attr;
res = _dwarf_pro_set_string_attr(new_attr,ownerdie->di_dbg,
string,error);
if
(res != DW_DLV_OK) {
return
res;
}
_dwarf_pro_add_at_to_die(ownerdie, new_attr);
*attr_out = new_attr;
return
DW_DLV_OK;
}
Dwarf_P_Attribute
dwarf_add_AT_const_value_string(Dwarf_P_Die ownerdie,
char
*string_value, Dwarf_Error * error)
{
Dwarf_P_Attribute a = 0;
int
res = 0;
res = dwarf_add_AT_const_value_string_a(ownerdie,
string_value,&a,error);
if
(res != DW_DLV_OK) {
return
(Dwarf_P_Attribute) DW_DLV_BADADDR;
}
return
a;
}
int
dwarf_add_AT_const_value_string_a(Dwarf_P_Die ownerdie,
char
*string_value,
Dwarf_P_Attribute *attr_out,
Dwarf_Error * error)
{
Dwarf_P_Attribute new_attr = 0;
Dwarf_P_Debug dbg = 0;
int
res = 0;
if
(ownerdie == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
return
DW_DLV_ERROR;
}
dbg = ownerdie->di_dbg;
new_attr = (Dwarf_P_Attribute)
_dwarf_p_get_alloc(dbg,
sizeof
(
struct
Dwarf_P_Attribute_s));
if
(new_attr == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
new_attr->ar_attribute = DW_AT_const_value;
res = _dwarf_pro_set_string_attr(new_attr,dbg,
string_value,error);
if
(res != DW_DLV_OK) {
return
res;
}
_dwarf_pro_add_at_to_die(ownerdie, new_attr);
*attr_out = new_attr;
return
DW_DLV_OK;
}
Dwarf_P_Attribute
dwarf_add_AT_with_ref_sig8(Dwarf_P_Die ownerdie,
Dwarf_Half attrnum,
const
Dwarf_Sig8 *sig8_in,
Dwarf_Error * error)
{
Dwarf_P_Attribute a = 0;
int
res = 0;
res = dwarf_add_AT_with_ref_sig8_a(ownerdie,
attrnum,sig8_in,&a,error);
if
(res != DW_DLV_OK) {
return
((Dwarf_P_Attribute) DW_DLV_BADADDR);
}
return
a;
}
int
dwarf_add_AT_with_ref_sig8_a(Dwarf_P_Die ownerdie,
Dwarf_Half attrnum,
const
Dwarf_Sig8 *sig8_in,
Dwarf_P_Attribute * attr_out,
Dwarf_Error * error)
{
Dwarf_P_Attribute new_attr = 0;
Dwarf_P_Debug dbg = 0;
if
(ownerdie == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
return
DW_DLV_ERROR;
}
dbg = ownerdie->di_dbg;
new_attr = (Dwarf_P_Attribute)
_dwarf_p_get_alloc(dbg,
sizeof
(
struct
Dwarf_P_Attribute_s));
if
(new_attr == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
new_attr->ar_attribute = attrnum;
new_attr->ar_attribute_form = DW_FORM_ref_sig8;
new_attr->ar_nbytes =
sizeof
(Dwarf_Sig8);
new_attr->ar_next = 0;
new_attr->ar_data =
(
char
*) _dwarf_p_get_alloc(dbg,
sizeof
(Dwarf_Sig8));
if
(new_attr->ar_data == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
memcpy
(new_attr->ar_data,sig8_in,
sizeof
(Dwarf_Sig8));
new_attr->ar_rel_type = R_MIPS_NONE;
new_attr->ar_reloc_len = 0;
_dwarf_pro_add_at_to_die(ownerdie, new_attr);
*attr_out = new_attr;
return
DW_DLV_OK;
}
Dwarf_P_Attribute
dwarf_add_AT_producer(Dwarf_P_Die ownerdie,
char
*producer_string, Dwarf_Error * error)
{
Dwarf_P_Attribute a = 0;
int
res = 0;
res = dwarf_add_AT_producer_a(ownerdie,
producer_string,&a,error);
if
(res != DW_DLV_OK) {
return
((Dwarf_P_Attribute)DW_DLV_BADADDR);
}
return
a;
}
int
dwarf_add_AT_producer_a(Dwarf_P_Die ownerdie,
char
*producer_string,
Dwarf_P_Attribute *attr_out,
Dwarf_Error * error)
{
Dwarf_P_Attribute new_attr = 0;
Dwarf_P_Debug dbg = 0;
int
res = 0;
if
(ownerdie == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
return
DW_DLV_ERROR;
}
dbg = ownerdie->di_dbg;
new_attr = (Dwarf_P_Attribute)
_dwarf_p_get_alloc(dbg,
sizeof
(
struct
Dwarf_P_Attribute_s));
if
(new_attr == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
new_attr->ar_attribute = DW_AT_producer;
res = _dwarf_pro_set_string_attr(new_attr,dbg,
producer_string,error);
if
(res != DW_DLV_OK) {
return
res;
}
_dwarf_pro_add_at_to_die(ownerdie, new_attr);
*attr_out = new_attr;
return
DW_DLV_OK;
}
int
dwarf_add_AT_const_value_signedint_a(Dwarf_P_Die ownerdie,
Dwarf_Signed signed_value,
Dwarf_P_Attribute *attr_out,
Dwarf_Error * error)
{
int
res = 0;
res = dwarf_add_AT_any_value_sleb_a(
ownerdie,DW_AT_const_value,
signed_value,
attr_out, error);
return
res;
}
Dwarf_P_Attribute
dwarf_add_AT_const_value_signedint(Dwarf_P_Die ownerdie,
Dwarf_Signed signed_value,
Dwarf_Error * error)
{
Dwarf_P_Attribute a = 0;
int
res = 0;
res = dwarf_add_AT_any_value_sleb_a(
ownerdie,DW_AT_const_value,
signed_value,
&a, error);
if
(res != DW_DLV_OK) {
return
(Dwarf_P_Attribute)DW_DLV_BADADDR;
}
return
a;
}
int
dwarf_add_AT_implicit_const(Dwarf_P_Die ownerdie,
Dwarf_Half attrnum,
Dwarf_Signed signed_value,
Dwarf_P_Attribute *outattr,
Dwarf_Error * error)
{
Dwarf_P_Attribute new_attr = 0;
Dwarf_P_Debug dbg = 0;
if
(ownerdie == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
return
DW_DLV_ERROR;
}
dbg = ownerdie->di_dbg;
new_attr = (Dwarf_P_Attribute)
_dwarf_p_get_alloc(dbg,
sizeof
(
struct
Dwarf_P_Attribute_s));
if
(new_attr == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
new_attr->ar_attribute = attrnum;
new_attr->ar_attribute_form = DW_FORM_implicit_const;
new_attr->ar_rel_type = R_MIPS_NONE;
new_attr->ar_reloc_len = 0;
new_attr->ar_next = 0;
new_attr->ar_data = 0;
new_attr->ar_nbytes = 0;
new_attr->ar_implicit_const = signed_value;
_dwarf_pro_add_at_to_die(ownerdie, new_attr);
*outattr = new_attr;
return
DW_DLV_OK;
}
Dwarf_P_Attribute
dwarf_add_AT_any_value_sleb(Dwarf_P_Die ownerdie,
Dwarf_Half attrnum,
Dwarf_Signed signed_value,
Dwarf_Error * error)
{
int
res = 0;
Dwarf_P_Attribute a = 0;
res = dwarf_add_AT_any_value_sleb_a(ownerdie,
attrnum,
signed_value,
&a, error);
if
(res != DW_DLV_OK) {
return
((Dwarf_P_Attribute) DW_DLV_BADADDR);
}
return
a;
}
int
dwarf_add_AT_any_value_sleb_a(Dwarf_P_Die ownerdie,
Dwarf_Half attrnum,
Dwarf_Signed signed_value,
Dwarf_P_Attribute *attr_out,
Dwarf_Error * error)
{
Dwarf_P_Attribute new_attr = 0;
int
leb_size = 0;
Dwarf_P_Debug dbg = 0;
char
encode_buffer[ENCODE_SPACE_NEEDED];
int
res = 0;
if
(ownerdie == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
return
DW_DLV_ERROR;
}
dbg = ownerdie->di_dbg;
new_attr = (Dwarf_P_Attribute)
_dwarf_p_get_alloc(dbg,
sizeof
(
struct
Dwarf_P_Attribute_s));
if
(new_attr == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
new_attr->ar_attribute = attrnum;
new_attr->ar_attribute_form = DW_FORM_sdata;
new_attr->ar_rel_type = R_MIPS_NONE;
new_attr->ar_reloc_len = 0;
new_attr->ar_next = 0;
res = _dwarf_pro_encode_signed_leb128_nm(signed_value, &leb_size,
encode_buffer,
sizeof
(encode_buffer));
if
(res != DW_DLV_OK) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
new_attr->ar_data = (
char
*)
_dwarf_p_get_alloc(dbg, leb_size);
if
(new_attr->ar_data == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
memcpy
(new_attr->ar_data, encode_buffer, leb_size);
new_attr->ar_nbytes = leb_size;
_dwarf_pro_add_at_to_die(ownerdie, new_attr);
*attr_out = new_attr;
return
DW_DLV_OK;
}
Dwarf_P_Attribute
dwarf_add_AT_const_value_unsignedint(Dwarf_P_Die ownerdie,
Dwarf_Unsigned unsigned_value,
Dwarf_Error * error)
{
Dwarf_P_Attribute a =0;
int
res = 0;
res = dwarf_add_AT_any_value_uleb_a(
ownerdie,DW_AT_const_value,
unsigned_value,
&a,
error);
if
(res != DW_DLV_OK) {
return
((Dwarf_P_Attribute) DW_DLV_BADADDR);
}
return
a;
}
int
dwarf_add_AT_const_value_unsignedint_a(Dwarf_P_Die ownerdie,
Dwarf_Unsigned unsigned_value,
Dwarf_P_Attribute *attr_out,
Dwarf_Error * error)
{
return
dwarf_add_AT_any_value_uleb_a(
ownerdie,DW_AT_const_value,
unsigned_value,
attr_out,
error);
}
int
dwarf_add_AT_data16(Dwarf_P_Die ownerdie,
Dwarf_Half attrnum,
Dwarf_Form_Data16 * ptr_to_val,
Dwarf_P_Attribute * attr_return,
Dwarf_Error * error)
{
Dwarf_P_Attribute new_attr;
int
val_size =
sizeof
(Dwarf_Form_Data16);
Dwarf_P_Debug dbg = 0;
if
(ownerdie == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
return
DW_DLV_ERROR;
}
dbg = ownerdie->di_dbg;
new_attr = (Dwarf_P_Attribute)
_dwarf_p_get_alloc(dbg,
sizeof
(
struct
Dwarf_P_Attribute_s));
if
(new_attr == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
new_attr->ar_attribute = attrnum;
new_attr->ar_attribute_form = DW_FORM_data16;
new_attr->ar_rel_type = R_MIPS_NONE;
new_attr->ar_reloc_len = 0;
new_attr->ar_next = 0;
new_attr->ar_data = (
char
*)
_dwarf_p_get_alloc(dbg, val_size);
if
(new_attr->ar_data == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
memcpy
(new_attr->ar_data, ptr_to_val->fd_data, val_size);
new_attr->ar_nbytes = val_size;
_dwarf_pro_add_at_to_die(ownerdie, new_attr);
*attr_return = new_attr;
return
DW_DLV_OK;
}
Dwarf_P_Attribute
dwarf_add_AT_any_value_uleb(Dwarf_P_Die ownerdie,
Dwarf_Half attrnum,
Dwarf_Unsigned unsigned_value,
Dwarf_Error * error)
{
Dwarf_P_Attribute a = 0;
int
res = 0;
res = dwarf_add_AT_any_value_uleb_a(ownerdie,
attrnum,unsigned_value,&a,error);
if
(res != DW_DLV_OK) {
return
((Dwarf_P_Attribute) DW_DLV_BADADDR);
}
return
a;
}
int
dwarf_add_AT_any_value_uleb_a(Dwarf_P_Die ownerdie,
Dwarf_Half attrnum,
Dwarf_Unsigned unsigned_value,
Dwarf_P_Attribute * attr_out,
Dwarf_Error * error)
{
Dwarf_P_Attribute new_attr;
int
leb_size;
Dwarf_P_Debug dbg = 0;
char
encode_buffer[ENCODE_SPACE_NEEDED];
int
res;
if
(ownerdie == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
return
DW_DLV_ERROR;
}
dbg = ownerdie->di_dbg;
new_attr = (Dwarf_P_Attribute)
_dwarf_p_get_alloc(dbg,
sizeof
(
struct
Dwarf_P_Attribute_s));
if
(new_attr == NULL) {
_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
new_attr->ar_attribute = attrnum;
new_attr->ar_attribute_form = DW_FORM_udata;
new_attr->ar_rel_type = R_MIPS_NONE;
new_attr->ar_reloc_len = 0;
new_attr->ar_next = 0;
res = _dwarf_pro_encode_leb128_nm(unsigned_value, &leb_size,
encode_buffer,
sizeof
(encode_buffer));
if
(res != DW_DLV_OK) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
new_attr->ar_data = (
char
*)
_dwarf_p_get_alloc(dbg, leb_size);
if
(new_attr->ar_data == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return
DW_DLV_ERROR;
}
memcpy
(new_attr->ar_data, encode_buffer, leb_size);
new_attr->ar_nbytes = leb_size;
_dwarf_pro_add_at_to_die(ownerdie, new_attr);
*attr_out = new_attr;
return
DW_DLV_OK;
}