Example #1
0
int
dwarf_end_macro_file(Dwarf_P_Debug dbg, Dwarf_Error * error)
{
    size_t length_est;
    int res;
    int compose_error_type;

    if (dbg == NULL) {
	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
	return (DW_DLV_ERROR);
    }
    length_est = COMMAND_LEN;
    res = libdwarf_compose_begin(dbg, DW_MACINFO_end_file, length_est,
				 &compose_error_type);
    if (res != DW_DLV_OK) {
	_dwarf_p_error(NULL, error, compose_error_type);
	return (DW_DLV_ERROR);
    }
    res = libdwarf_compose_complete(dbg, &compose_error_type);
    if (res != DW_DLV_OK) {
	_dwarf_p_error(NULL, error, compose_error_type);
	return (DW_DLV_ERROR);
    }
    res = libdwarf_compose_complete(dbg,
				    &compose_error_type);
    if (res != DW_DLV_OK) {
        _dwarf_p_error(NULL, error, compose_error_type);
        return(DW_DLV_ERROR);
    }
    return DW_DLV_OK;
}
Example #2
0
/* FIXME: Add stats for debug_line_str. */
int
dwarf_pro_get_string_stats(Dwarf_P_Debug dbg,
    Dwarf_Unsigned * str_count,
    Dwarf_Unsigned * str_total_length,
    Dwarf_Unsigned * strp_count_debug_str,
    Dwarf_Unsigned * strp_len_debug_str,
    Dwarf_Unsigned * strp_reused_count,
    Dwarf_Unsigned * strp_reused_len,
    Dwarf_Error    * error)
{
    struct Dwarf_P_Str_stats_s* ps = 0;
    if (!dbg) {
        _dwarf_p_error(dbg, error, DW_DLE_IA);
        return DW_DLV_ERROR;
    }
    if (dbg->de_version_magic_number !=PRO_VERSION_MAGIC ) {
        _dwarf_p_error(dbg, error, DW_DLE_VMM);
        return DW_DLV_ERROR;
    }
    *str_count        = dbg->de_stats.ps_str_count;
    *str_total_length = dbg->de_stats.ps_str_total_length;
    ps = &dbg->de_stats.ps_strp;
    *strp_count_debug_str = ps->ps_strp_count_debug_str;
    *strp_len_debug_str   = ps->ps_strp_len_debug_str;
    *strp_reused_count    = ps->ps_strp_reused_count;
    *strp_reused_len      = ps->ps_strp_reused_len;
    return DW_DLV_OK;
}
Example #3
0
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;
}
Example #4
0
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 new_attr = 0;
    if (ownerdie == NULL) {
        _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
    }

    new_attr = (Dwarf_P_Attribute)
        _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s));
    if (new_attr == NULL) {
        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
    }
    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(ownerdie->di_dbg, sizeof(Dwarf_Sig8));
    if (new_attr->ar_data == NULL) {
        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
    }
    memcpy(new_attr->ar_data,sig8_in,sizeof(Dwarf_Sig8));
    new_attr->ar_rel_type = R_MIPS_NONE;
    new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */
    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
    return new_attr;
}
Example #5
0
int
dwarf_force_debug_names(Dwarf_P_Debug dbg,
    Dwarf_Error * error)
{

    Dwarf_P_Dnames dn;

    if (dbg == NULL) {
        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
        return DW_DLV_ERROR;
    }

    dn = (Dwarf_P_Dnames)
        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Dnames_s));
    if (dn == NULL) {
        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
        return DW_DLV_ERROR;
    }
    if (!dbg->de_dnames) {
        dbg->de_dnames = dn;
    }
    dn->dn_create_section = TRUE;

    return DW_DLV_OK;
}
Example #6
0
/* Make sure attribute types are checked before entering here. */
static Dwarf_P_Attribute
local_add_AT_address(Dwarf_P_Debug dbg,
    Dwarf_P_Die ownerdie,
    Dwarf_Half attr,
    Dwarf_Signed form,
    Dwarf_Unsigned pc_value,
    Dwarf_Unsigned sym_index,
    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 ((Dwarf_P_Attribute) DW_DLV_BADADDR);
    }
    upointer_size = dbg->de_pointer_size;

    if (ownerdie == NULL) {
        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
    }

    /* attribute types have already been checked */
    /* switch (attr) { ... } */

    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 ((Dwarf_P_Attribute) DW_DLV_BADADDR);
    }

    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 ((Dwarf_P_Attribute) DW_DLV_BADADDR);
    }
    WRITE_UNALIGNED(dbg, new_attr->ar_data,
        (const void *) &pc_value,
        sizeof(pc_value), upointer_size);

    /* add attribute to the die */
    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
    return new_attr;
}
Example #7
0
/*
    This function adds values of attributes
    belonging to the string class.
*/
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 new_attr;

    if (dbg == NULL) {
	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
    }

    if (ownerdie == NULL) {
	_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
    }

    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 ((Dwarf_P_Attribute) DW_DLV_BADADDR);
    }

    switch (attr) {
    case DW_AT_name:
    case DW_AT_comp_dir:
    case DW_AT_const_value:
    case DW_AT_producer:
    case DW_AT_MIPS_linkage_name:
    case DW_AT_MIPS_abstract_name:
	break;

    default:{
	    _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
	    return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
	}
    }

    new_attr->ar_attribute = attr;
    new_attr->ar_attribute_form = DW_FORM_string;
    new_attr->ar_nbytes = strlen(string) + 1;
    new_attr->ar_next = 0;

    new_attr->ar_data =
	(char *) _dwarf_p_get_alloc(NULL, strlen(string) + 1);
    if (new_attr->ar_data == NULL) {
	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
    }

    strcpy(new_attr->ar_data, string);
    new_attr->ar_rel_type = R_MIPS_NONE;
    new_attr->ar_reloc_len = 0;	/* unused for R_MIPS_NONE */

    /* add attribute to the die */
    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
    return new_attr;
}
Example #8
0
/*
  The following is the generic 'add a simple name entry'
  for any of the simple name sections. 

  See enum dwarf_sn_kind in pro_opaque.h
 
*/
Dwarf_Unsigned
_dwarf_add_simple_name_entry(Dwarf_P_Debug dbg,
			     Dwarf_P_Die die,
			     char *entry_name,
			     enum dwarf_sn_kind entrykind,
			     Dwarf_Error * error)
{
    Dwarf_P_Simple_nameentry nameentry;
    Dwarf_P_Simple_name_header hdr;
    char *name;
    int uword_size;

    if (dbg == NULL) {
	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
	return (0);
    }

    if (die == NULL) {
	_dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
	return (0);
    }


    nameentry = (Dwarf_P_Simple_nameentry)
	_dwarf_p_get_alloc(dbg,
			   sizeof(struct Dwarf_P_Simple_nameentry_s));
    if (nameentry == NULL) {
	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
	return (0);
    }

    name = _dwarf_p_get_alloc(dbg, strlen(entry_name) + 1);
    if (name == NULL) {
	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
	return (0);
    }
    strcpy(name, entry_name);

    nameentry->sne_die = die;
    nameentry->sne_name = name;
    nameentry->sne_name_len = strlen(name);
    uword_size = dbg->de_offset_size;

    hdr = &dbg->de_simple_name_headers[entrykind];
    if (hdr->sn_head == NULL)
	hdr->sn_head = hdr->sn_tail = nameentry;
    else {
	hdr->sn_tail->sne_next = nameentry;
	hdr->sn_tail = nameentry;
    }
    hdr->sn_count++;
    hdr->sn_net_len += uword_size + nameentry->sne_name_len + 1;

    return (1);
}
Example #9
0
/* Similar to dwarf_add_fde_inst, except that the offset denoted by VAL2
   is signed.
*/
Dwarf_P_Fde
dwarf_add_fde_inst_with_signed_offset(Dwarf_P_Fde fde,
                                      Dwarf_Small op,
                                      Dwarf_Unsigned val1,
                                      Dwarf_Signed val2, Dwarf_Error * error)
{
    Dwarf_P_Frame_Pgm curinst;
    int nbytes, nbytes1, nbytes2;
    char *ptr;
    int res;
    char buff1[ENCODE_SPACE_NEEDED];
    char buff2[ENCODE_SPACE_NEEDED];


    nbytes = 0;
    ptr = NULL;
    curinst = (Dwarf_P_Frame_Pgm)
        _dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Frame_Pgm_s));
    if (curinst == NULL) {
        _dwarf_p_error(NULL, error, DW_DLE_FPGM_ALLOC);
        return ((Dwarf_P_Fde) DW_DLV_BADADDR);
    }

    if (op == DW_CFA_offset_extended_sf)
    {
      res = _dwarf_pro_encode_leb128_nm(val1, &nbytes1,
                                        buff1, sizeof(buff1));
      if (res != DW_DLV_OK) {
        _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
        return ((Dwarf_P_Fde) DW_DLV_BADADDR);
      }
      res = _dwarf_pro_encode_signed_leb128_nm(val2, &nbytes2,
                                               buff2, sizeof(buff2));
      if (res != DW_DLV_OK) {
        _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
        return ((Dwarf_P_Fde) DW_DLV_BADADDR);
      }
      ptr = (char *) _dwarf_p_get_alloc(NULL, nbytes1 + nbytes2);
      if (ptr == NULL) {
        _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
        return ((Dwarf_P_Fde) DW_DLV_BADADDR);
      }
      memcpy(ptr, buff1, nbytes1);
      memcpy(ptr + nbytes1, buff2, nbytes2);
      nbytes = nbytes1 + nbytes2;
    }
    curinst->dfp_opcode = op;
    curinst->dfp_args = ptr;
    curinst->dfp_nbytes = nbytes;
    curinst->dfp_next = NULL;

    _dwarf_pro_add_to_fde(fde, curinst);
    return fde;
}
Example #10
0
Dwarf_Unsigned
dwarf_add_expr_addr_b (
    Dwarf_P_Expr	expr,
    Dwarf_Unsigned	addr,
    Dwarf_Unsigned	sym_index,
    Dwarf_Error		*error
)
{
    Dwarf_P_Debug		dbg;
    Dwarf_Small		*next_byte_ptr;
    Dwarf_Unsigned	next_byte_offset;
    int upointer_size;

    if (expr == NULL) {
	_dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
	return(DW_DLV_NOCOUNT);
    }

    dbg = expr->ex_dbg;
    if (dbg == NULL) {
	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
	return(DW_DLV_NOCOUNT);
    }

    upointer_size = dbg->de_pointer_size;
    next_byte_offset = expr->ex_next_byte_offset + upointer_size + 1;
    if (next_byte_offset > MAXIMUM_LOC_EXPR_LENGTH) {
	_dwarf_p_error(dbg, error, DW_DLE_EXPR_LENGTH_BAD);
	return(DW_DLV_NOCOUNT);
    }

    next_byte_ptr = &(expr->ex_byte_stream[0]) + expr->ex_next_byte_offset;

    *next_byte_ptr = DW_OP_addr;
    next_byte_ptr++;
    WRITE_UNALIGNED (dbg,next_byte_ptr,(const void *)&addr,
		sizeof(addr),upointer_size);

    if (expr->ex_reloc_offset != 0) {
	_dwarf_p_error(dbg, error, DW_DLE_MULTIPLE_RELOC_IN_EXPR);
	return(DW_DLV_NOCOUNT);
    }

    expr->ex_reloc_sym_index = sym_index;
    expr->ex_reloc_offset = expr->ex_next_byte_offset + 1;

    expr->ex_next_byte_offset = next_byte_offset;
    return(next_byte_offset);
}
Example #11
0
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 new_attr;
    int leb_size;
    char encode_buffer[ENCODE_SPACE_NEEDED];
    int res;

    if (ownerdie == NULL) {
        _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
    }

    new_attr = (Dwarf_P_Attribute)
        _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s));
    if (new_attr == NULL) {
        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
    }

    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; /* unused for R_MIPS_NONE */
    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(NULL, error, DW_DLE_ALLOC_FAIL);
        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
    }
    new_attr->ar_data = (char *)
        _dwarf_p_get_alloc(ownerdie->di_dbg, leb_size);
    if (new_attr->ar_data == NULL) {
        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
    }
    memcpy(new_attr->ar_data, encode_buffer, leb_size);
    new_attr->ar_nbytes = leb_size;

    /* add attribute to the die */
    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
    return new_attr;
}
Example #12
0
Dwarf_Unsigned
dwarf_expr_current_offset(Dwarf_P_Expr expr, Dwarf_Error * error)
{
    if (expr == NULL) {
	_dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
	return (DW_DLV_NOCOUNT);
    }

    if (expr->ex_dbg == NULL) {
	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
	return (DW_DLV_NOCOUNT);
    }

    return (expr->ex_next_byte_offset);
}
Example #13
0
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)
{
    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 ((Dwarf_P_Attribute) DW_DLV_BADADDR);
        }
        break;
    }

    /*  FIXME: For DWARF3 and later this call is problematic as
        DW_FORM_ref_addr is really an offset in
        .debug_info , not an address.  */
    return local_add_AT_address(dbg, ownerdie, attr, DW_FORM_ref_addr,
        pc_value, sym_index, error);
}
Example #14
0
/*  Add a cfe_offset instruction to the fde passed in. */
Dwarf_P_Fde
dwarf_fde_cfa_offset(Dwarf_P_Fde fde,
    Dwarf_Unsigned reg,
    Dwarf_Signed offset, Dwarf_Error * error)
{
    Dwarf_Ubyte opc, regno;
    char *ptr = 0;
    Dwarf_P_Frame_Pgm curinst;
    int nbytes = 0;
    int res = 0;
    char buff1[ENCODE_SPACE_NEEDED];
    Dwarf_P_Debug dbg = fde->fde_dbg;

    curinst = (Dwarf_P_Frame_Pgm)
        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Frame_Pgm_s));
    if (curinst == NULL) {
        DWARF_P_DBG_ERROR(dbg, DW_DLE_FPGM_ALLOC,
            (Dwarf_P_Fde) DW_DLV_BADADDR);
    }
    opc = DW_CFA_offset;
    regno = reg;
    if (regno & 0xc0) {
        DWARF_P_DBG_ERROR(dbg, DW_DLE_REGNO_OVFL,
            (Dwarf_P_Fde) DW_DLV_BADADDR);
    }
    opc = opc | regno;          /* lower 6 bits are register number */
    curinst->dfp_opcode = opc;
    res = _dwarf_pro_encode_leb128_nm(offset, &nbytes,
        buff1, sizeof(buff1));
    if (res != DW_DLV_OK) {
        _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
        return ((Dwarf_P_Fde) DW_DLV_BADADDR);
    }
    ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes);
    if (ptr == NULL) {
        _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
        return ((Dwarf_P_Fde) DW_DLV_BADADDR);
    }
    memcpy(ptr, buff1, nbytes);

    curinst->dfp_args = ptr;
    curinst->dfp_nbytes = nbytes;
    curinst->dfp_next = NULL;

    _dwarf_pro_add_to_fde(fde, curinst);
    return fde;
}
Example #15
0
void
dwarf_expr_reset(Dwarf_P_Expr expr, Dwarf_Error * error)
{
   if (expr == NULL) {
      _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
      return;
   }
   expr->ex_next_byte_offset=0;
}
Example #16
0
/* This function adds attributes of the flag class.  */
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 new_attr = 0;

    if (dbg == NULL) {
        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
    }

    if (ownerdie == NULL) {
        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
    }

    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 ((Dwarf_P_Attribute) DW_DLV_BADADDR);
    }

    new_attr->ar_attribute = attr;
    new_attr->ar_attribute_form = DW_FORM_flag;
    new_attr->ar_nbytes = 1;
    new_attr->ar_reloc_len = 0; /* not used */
    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 ((Dwarf_P_Attribute) DW_DLV_BADADDR);
    }
    memcpy(new_attr->ar_data, &flag, 1);

    /* Add attribute to the die */
    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
    return new_attr;
}
Example #17
0
int
_dwarf_pro_transform_macro_info_to_disk(Dwarf_P_Debug dbg,
					Dwarf_Error * error)
{
    /* Total num of bytes in .debug_macinfo section. */
    Dwarf_Unsigned mac_num_bytes;

    /* Points to first byte of .debug_macinfo buffer. */
    Dwarf_Small *macinfo;

    /* Fills in the .debug_macinfo buffer. */
    Dwarf_Small *macinfo_ptr;


    /* Used to scan the section data buffers. */
    struct dw_macinfo_block_s *m_prev;
    struct dw_macinfo_block_s *m_sect;


    /* Get the size of the debug_macinfo data */
    mac_num_bytes = 0;
    for (m_sect = dbg->de_first_macinfo; m_sect != NULL;
	 m_sect = m_sect->mb_next) {
	mac_num_bytes += m_sect->mb_used_len;
    }
    /* Tthe final entry has a type code of 0 to indicate It is final
       for this CU Takes just 1 byte. */
    mac_num_bytes += 1;

    GET_CHUNK(dbg, dbg->de_elf_sects[DEBUG_MACINFO],
	      macinfo, (unsigned long) mac_num_bytes, error);
    if (macinfo == NULL) {
	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
	return (0);
    }

    macinfo_ptr = macinfo;
    m_prev = 0;
    for (m_sect = dbg->de_first_macinfo; m_sect != NULL;
	 m_sect = m_sect->mb_next) {
	memcpy(macinfo_ptr, m_sect->mb_data, m_sect->mb_used_len);
	macinfo_ptr += m_sect->mb_used_len;
	if (m_prev) {
	    _dwarf_p_dealloc(dbg, (Dwarf_Small *) m_prev);
	    m_prev = 0;
	}
	m_prev = m_sect;
    }
    *macinfo_ptr = 0;		/* the type code of 0 as last entry */
    if (m_prev) {
	_dwarf_p_dealloc(dbg, (Dwarf_Small *) m_prev);
	m_prev = 0;
    }

    return (int) dbg->de_n_debug_sect;
}
Example #18
0
Dwarf_Addr
dwarf_expr_into_block (
    Dwarf_P_Expr	expr,
    Dwarf_Unsigned	*length,
    Dwarf_Error		*error
)
{
    if (expr == NULL) {
	_dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
	return(DW_DLV_BADADDR);
    }

    if (expr->ex_dbg == NULL) {
	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
	return(DW_DLV_BADADDR);
    }

    if (length != NULL) *length = expr->ex_next_byte_offset;
    return((Dwarf_Addr)&(expr->ex_byte_stream[0]));
}
Example #19
0
/*
    This function creates a new expression 
    struct that can be used to build up a
    location expression.
*/
Dwarf_P_Expr
dwarf_new_expr(Dwarf_P_Debug dbg, Dwarf_Error * error)
{
    Dwarf_P_Expr ret_expr;

    if (dbg == NULL) {
	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
	return (NULL);
    }

    ret_expr = (Dwarf_P_Expr)
	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Expr_s));
    if (ret_expr == NULL) {
	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
	return (NULL);
    }

    ret_expr->ex_dbg = dbg;

    return (ret_expr);
}
Example #20
0
/* Write line number first, then file index. */
int
dwarf_start_macro_file(Dwarf_P_Debug dbg,
		       Dwarf_Unsigned fileindex,
		       Dwarf_Unsigned linenumber, Dwarf_Error * error)
{
    size_t length_est;
    int res;
    int compose_error_type;

    if (dbg == NULL) {
	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
	return (DW_DLV_ERROR);
    }
    length_est = COMMAND_LEN + LINE_LEN + LINE_LEN;
    res = libdwarf_compose_begin(dbg, DW_MACINFO_start_file, length_est,
				 &compose_error_type);
    if (res != DW_DLV_OK) {
	_dwarf_p_error(NULL, error, compose_error_type);
	return (DW_DLV_ERROR);
    }
    res = libdwarf_compose_add_line(dbg, linenumber,
				    &compose_error_type);
    if (res != DW_DLV_OK) {
	_dwarf_p_error(NULL, error, compose_error_type);
	return (DW_DLV_ERROR);
    }
    res = libdwarf_compose_add_line(dbg, fileindex,
				    &compose_error_type);
    if (res != DW_DLV_OK) {
	_dwarf_p_error(NULL, error, compose_error_type);
	return (DW_DLV_ERROR);
    }
    res = libdwarf_compose_complete(dbg,
				    &compose_error_type);
    if (res != DW_DLV_OK) {
	_dwarf_p_error(NULL, error, compose_error_type);
	return (DW_DLV_ERROR);
    }
    return DW_DLV_OK;
}
Example #21
0
Dwarf_Addr
dwarf_expr_into_block(Dwarf_P_Expr expr,
		      Dwarf_Unsigned * length, Dwarf_Error * error)
{
    if (expr == NULL) {
	_dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
	return (DW_DLV_BADADDR);
    }

    if (expr->ex_dbg == NULL) {
	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
	return (DW_DLV_BADADDR);
    }

    if (length != NULL)
	*length = expr->ex_next_byte_offset;
    /* The following cast from pointer to integer is ok as long as
       Dwarf_Addr is at least as large as a pointer. Which is a
       requirement of libdwarf so must be satisfied (some compilers
       emit a warning about the following line). */
    return ((Dwarf_Addr) (unsigned long) & (expr->ex_byte_stream[0]));
}
Example #22
0
/*  This function adds another address range
    to the list of address ranges for the
    given Dwarf_P_Debug.  It returns 0 on error,
    and 1 otherwise.  */
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);
}
Example #23
0
Dwarf_P_Attribute
dwarf_add_AT_producer(Dwarf_P_Die ownerdie,
		      char *producer_string, Dwarf_Error * error)
{
    Dwarf_P_Attribute new_attr;

    if (ownerdie == NULL) {
	_dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
    }

    new_attr = (Dwarf_P_Attribute)
	_dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Attribute_s));
    if (new_attr == NULL) {
	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
    }

    new_attr->ar_attribute = DW_AT_producer;
    new_attr->ar_attribute_form = DW_FORM_string;
    new_attr->ar_nbytes = strlen(producer_string) + 1;
    new_attr->ar_next = 0;

    new_attr->ar_data =
	(char *) _dwarf_p_get_alloc(NULL, strlen(producer_string) + 1);
    if (new_attr->ar_data == NULL) {
	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
    }

    strcpy(new_attr->ar_data, producer_string);
    new_attr->ar_rel_type = R_MIPS_NONE;
    new_attr->ar_reloc_len = 0;	/* unused for R_MIPS_NONE */

    /* add attribute to the die */
    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
    return new_attr;
}
Example #24
0
int
dwarf_undef_macro(Dwarf_P_Debug dbg,
		  Dwarf_Unsigned line,
		  char *macname, Dwarf_Error * error)
{

    size_t len;
    size_t length_est;
    int res;
    int compose_error_type;

    if (dbg == NULL) {
	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
	return (DW_DLV_ERROR);
    }
    if (macname == 0) {
	_dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL);
	return (DW_DLV_ERROR);
    }
#ifdef TARG_IA64
    len = strlen(macname) + 1;
#else
    len = strlen(macname);
#endif
    if (len == 0) {
	_dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY);
	return (DW_DLV_ERROR);
    }
#ifdef TARG_IA64
    length_est = COMMAND_LEN + LINE_LEN + len;
#else
    length_est = COMMAND_LEN + LINE_LEN + len + 1;
#endif
    res = libdwarf_compose_begin(dbg, DW_MACINFO_undef, length_est,
				 &compose_error_type);
    if (res != DW_DLV_OK) {
	_dwarf_p_error(NULL, error, compose_error_type);
	return (DW_DLV_ERROR);
    }
    res = libdwarf_compose_add_line(dbg, line, &compose_error_type);
    if (res != DW_DLV_OK) {
	_dwarf_p_error(NULL, error, compose_error_type);
	return (DW_DLV_ERROR);
    }
    libdwarf_compose_add_string(dbg, macname, len);
    res = libdwarf_compose_complete(dbg, &compose_error_type);
    if (res != DW_DLV_OK) {
	_dwarf_p_error(NULL, error, compose_error_type);
	return (DW_DLV_ERROR);
    }
    return DW_DLV_OK;
}
Example #25
0
/*  New interface, replacing dwarf_add_AT_targ_address.
    Essentially just makes sym_index a Dwarf_Unsigned
    so for symbolic relocations it can be a full address.  */
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)
{
    switch (attr) {
    case DW_AT_low_pc:
    case DW_AT_high_pc:

    /* added to support location lists */
    /* no way to check that this is a loclist-style address though */
    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: /* Gcc can generate this as address. */
    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 ((Dwarf_P_Attribute) DW_DLV_BADADDR);
        }
        break;
    }

    return local_add_AT_address(dbg, ownerdie, attr, DW_FORM_addr,
        pc_value, sym_index, error);
}
Example #26
0
int
_dwarf_transform_arange_to_disk(Dwarf_P_Debug dbg,
    Dwarf_Signed *nbufs, Dwarf_Error * error)
{
    /* Total num of bytes in .debug_aranges section. */
    Dwarf_Unsigned arange_num_bytes = 0;

    /*  Adjustment to align the start of the actual address ranges on a
        boundary aligned with twice the address size. */
    Dwarf_Small remainder = 0;

    /*  Total number of bytes excluding the length field. */
    Dwarf_Unsigned adjusted_length = 0;

    /*  Points to first byte of .debug_aranges buffer. */
    Dwarf_Small *arange = 0;

    /*  Fills in the .debug_aranges buffer. */
    Dwarf_Small *arange_ptr = 0;

    /*  Scans the list of address ranges provided by user. */
    Dwarf_P_Arange given_arange = 0;

    /*  Used to fill in 0. */
    const Dwarf_Signed big_zero = 0;

    int extension_word_size = dbg->de_64bit_extension ? 4 : 0;
    int offset_size = dbg->de_offset_size;
    int upointer_size = dbg->de_pointer_size;

    /*  All dwarf versions so far use 2 here. */
    Dwarf_Half version = 2;
    int res = 0;


    /* ***** BEGIN CODE ***** */

    /* Size of the .debug_aranges section header. */
    arange_num_bytes = extension_word_size +
        offset_size +       /* Size of length field.  */
        DWARF_HALF_SIZE +    /* Size of version field. */
        offset_size +            /* Size of .debug_info offset. */
        sizeof(Dwarf_Small) +   /* Size of address size field. */
        sizeof(Dwarf_Small);    /* Size of segment size field. */

    /*  Adjust the size so that the set of aranges begins on a boundary
        that aligned with twice the address size.  This is a Libdwarf
        requirement. */
    remainder = arange_num_bytes % (2 * upointer_size);
    if (remainder != 0)
        arange_num_bytes += (2 * upointer_size) - remainder;


    /* Add the bytes for the actual address ranges. */
    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 (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;
    }

    /* Write the total length of .debug_aranges section. */
    adjusted_length = arange_num_bytes - offset_size
        - extension_word_size;
    {
        Dwarf_Unsigned du = adjusted_length;

        WRITE_UNALIGNED(dbg, (void *) arange_ptr,
            (const void *) &du, sizeof(du), offset_size);
        arange_ptr += offset_size;
    }

    /* Write the version as 2 bytes. */
    {
        Dwarf_Half verstamp = version;

        WRITE_UNALIGNED(dbg, (void *) arange_ptr,
            (const void *) &verstamp,
            sizeof(verstamp), DWARF_HALF_SIZE);
        arange_ptr += DWARF_HALF_SIZE;
    }


    /* Write the .debug_info offset.  This is always 0. */
    WRITE_UNALIGNED(dbg, (void *) arange_ptr,
        (const void *) &big_zero,
        sizeof(big_zero), offset_size);
    arange_ptr += offset_size;

    {
        unsigned long count = dbg->de_arange_count + 1;
        int res2 = 0;
        Dwarf_P_Per_Reloc_Sect p_reloc =
            &dbg->de_reloc_sect[DEBUG_ARANGES];

        if (dbg->de_relocate_pair_by_symbol) {
            count = (3 * dbg->de_arange_count) + 1;
        }
        /*  The following is a small optimization: not needed for
            correctness.  Does nothing if
            preloc->pr_first_block is non-null */
        res2 = _dwarf_pro_pre_alloc_specific_reloc_slots(dbg,
            p_reloc, count);
        if (res2 != DW_DLV_OK) {
            _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
            return DW_DLV_ERROR;
        }
    }

    /* reloc for .debug_info */
    res = dbg->de_relocate_by_name_symbol(dbg,
        DEBUG_ARANGES,
        extension_word_size +
        offset_size + DWARF_HALF_SIZE,
        dbg->de_sect_name_idx[DEBUG_INFO],
        dwarf_drt_data_reloc, offset_size);

    /* Write the size of addresses. */
    *arange_ptr = dbg->de_pointer_size;
    arange_ptr++;

    /*  Write the size of segment addresses. This is zero for MIPS
        architectures. */
    *arange_ptr = 0;
    arange_ptr++;

    /*  Skip over the padding to align the start of the actual address
        ranges to twice the address size. */
    if (remainder != 0)
        arange_ptr += (2 * upointer_size) - remainder;





    /*  The arange address, length are pointer-size fields of the target
        machine. */
    for (given_arange = dbg->de_arange; given_arange != NULL;
        given_arange = given_arange->ag_next) {

        /* Write relocation record for beginning of address range. */
        res = dbg->de_relocate_by_name_symbol(dbg, DEBUG_ARANGES,
            arange_ptr - arange,       /* r_offset */
            (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 DW_DLV_ERROR;
        }

        /* Copy beginning address of range. */
        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_relocate_pair_by_symbol &&
            given_arange->ag_end_symbol_index != 0 &&
            given_arange->ag_length == 0) {
            /*  symbolic reloc, need reloc for length What if we really
                know the length? If so, should use the other part of
                'if'. */
            Dwarf_Unsigned val;

            res = dbg->de_relocate_pair_by_symbol(dbg,
                DEBUG_ARANGES,
                arange_ptr - arange,   /* r_offset */
                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 DW_DLV_ERROR;
            }

            /*  arange pre-calc so assem text can do .word end - begin
                + val (gets val from stream) */
            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 {
            /* plain old length to copy, no relocation at all */
            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);
    *nbufs =  dbg->de_n_debug_sect;
    return DW_DLV_OK;
}
Example #27
0
/*
    Generic routine to add opcode to fde instructions. val1 and
    val2 are parameters whose interpretation depends on the 'op'.

    This does not work properly for  DW_DLC_SYMBOLIC_RELOCATIONS
    for DW_CFA_set_loc or DW_DVA_advance_loc* 'op', as
    these ops normally are addresses or (DW_CFA_set_loc) 
    or code lengths (DW_DVA_advance_loc*) and such must be
    represented with relocations and symbol indices for
    DW_DLC_SYMBOLIC_RELOCATIONS.

*/
Dwarf_P_Fde
dwarf_add_fde_inst(Dwarf_P_Fde fde,
		   Dwarf_Small op,
		   Dwarf_Unsigned val1,
		   Dwarf_Unsigned val2, Dwarf_Error * error)
{
    Dwarf_P_Frame_Pgm curinst;
    int nbytes, nbytes1, nbytes2;
    Dwarf_Ubyte db;
    Dwarf_Half dh;
    Dwarf_Word dw;
    Dwarf_Unsigned du;
    char *ptr;
    int res;
    char buff1[ENCODE_SPACE_NEEDED];
    char buff2[ENCODE_SPACE_NEEDED];


    nbytes = 0;
    ptr = NULL;
    curinst = (Dwarf_P_Frame_Pgm)
	_dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Frame_Pgm_s));
    if (curinst == NULL) {
	_dwarf_p_error(NULL, error, DW_DLE_FPGM_ALLOC);
	return ((Dwarf_P_Fde) DW_DLV_BADADDR);
    }

    switch (op) {

#ifdef TARG_X8664
	case DW_CFA_advance_loc4:
	    // We will use 2 half-words to copy the labels; cg will later
	    // fix the relocatable symbols.
	    dh = val1;
	    ptr = (char *) _dwarf_p_get_alloc(NULL, 4);
	    if (ptr == NULL) {
	      _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
	      return((Dwarf_P_Fde)DW_DLV_BADADDR);
	    }
	    memcpy((void *)ptr, (const void *)&dh,2);
	    dh = val2;
	    memcpy((void *)ptr+2, (const void *)&dh,2);
	    nbytes = 4;
	    break;
#endif // TARG_X8664
    case DW_CFA_advance_loc:
	if (val1 <= 0x3f) {
	    db = val1;
	    op |= db;
	}
	/* test not portable FIX */
	else if (val1 <= UCHAR_MAX) {
	    op = DW_CFA_advance_loc1;
	    db = val1;
	    ptr = (char *) _dwarf_p_get_alloc(NULL, 1);
	    if (ptr == NULL) {
		_dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
	    }
	    memcpy((void *) ptr, (const void *) &db, 1);
	    nbytes = 1;
	}
	/* test not portable FIX */
	else if (val1 <= USHRT_MAX) {
	    op = DW_CFA_advance_loc2;
	    dh = val1;
	    ptr = (char *) _dwarf_p_get_alloc(NULL, 2);
	    if (ptr == NULL) {
		_dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
	    }
	    memcpy((void *) ptr, (const void *) &dh, 2);
	    nbytes = 2;
	}
	/* test not portable FIX */
	else if (val1 <= ULONG_MAX) {
	    op = DW_CFA_advance_loc4;
	    dw = (Dwarf_Word) val1;
	    ptr = (char *) _dwarf_p_get_alloc(NULL, 4);
	    if (ptr == NULL) {
		_dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
	    }
	    memcpy((void *) ptr, (const void *) &dw, 4);
	    nbytes = 4;
	} else {
	    op = DW_CFA_MIPS_advance_loc8;
	    du = val1;
	    ptr =
		(char *) _dwarf_p_get_alloc(NULL,
					    sizeof(Dwarf_Unsigned));
	    if (ptr == NULL) {
		_dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
	    }
	    memcpy((void *) ptr, (const void *) &du, 8);
	    nbytes = 8;
	}
	break;

    case DW_CFA_offset:
	if (val1 <= MAX_6_BIT_VALUE) {
	    db = val1;
	    op |= db;
	    res = _dwarf_pro_encode_leb128_nm(val2, &nbytes,
					      buff1, sizeof(buff1));
	    if (res != DW_DLV_OK) {
		_dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
	    }
	    ptr = (char *) _dwarf_p_get_alloc(NULL, nbytes);
	    if (ptr == NULL) {
		_dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
	    }
	    memcpy(ptr, buff1, nbytes);

	} else {
	    op = DW_CFA_offset_extended;

	    res = _dwarf_pro_encode_leb128_nm(val1, &nbytes1,
					      buff1, sizeof(buff1));
	    if (res != DW_DLV_OK) {
		_dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
	    }
	    res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2,
					      buff2, sizeof(buff2));
	    if (res != DW_DLV_OK) {
		_dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
	    }
	    ptr = (char *) _dwarf_p_get_alloc(NULL, nbytes1 + nbytes2);
	    if (ptr == NULL) {
		_dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
	    }
	    memcpy(ptr, buff1, nbytes1);
	    memcpy(ptr + nbytes1, buff2, nbytes2);
	    nbytes = nbytes1 + nbytes2;
	}
	break;

    case DW_CFA_undefined:
    case DW_CFA_same_value:
	res = _dwarf_pro_encode_leb128_nm(val1, &nbytes,
					  buff1, sizeof(buff1));
	if (res != DW_DLV_OK) {
	    _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
	    return ((Dwarf_P_Fde) DW_DLV_BADADDR);
	}
	ptr = (char *) _dwarf_p_get_alloc(NULL, nbytes);
	if (ptr == NULL) {
	    _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
	    return ((Dwarf_P_Fde) DW_DLV_BADADDR);
	}
	memcpy(ptr, buff1, nbytes);
	break;

    case DW_CFA_register:
    case DW_CFA_def_cfa:
	res = _dwarf_pro_encode_leb128_nm(val1, &nbytes1,
					  buff1, sizeof(buff1));
	if (res != DW_DLV_OK) {
	    _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
	    return ((Dwarf_P_Fde) DW_DLV_BADADDR);
	}

	res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2,
					  buff2, sizeof(buff2));
	if (res != DW_DLV_OK) {
	    _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
	    return ((Dwarf_P_Fde) DW_DLV_BADADDR);
	}

	ptr = (char *) _dwarf_p_get_alloc(NULL, nbytes1 + nbytes2);
	if (ptr == NULL) {
	    _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
	    return ((Dwarf_P_Fde) DW_DLV_BADADDR);
	}
	memcpy(ptr, buff1, nbytes1);
	memcpy(ptr + nbytes1, buff2, nbytes2);
	nbytes = nbytes1 + nbytes2;
	break;

    case DW_CFA_def_cfa_register:
    case DW_CFA_def_cfa_offset:
	res = _dwarf_pro_encode_leb128_nm(val1, &nbytes,
					  buff1, sizeof(buff1));
	if (res != DW_DLV_OK) {
	    _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
	    return ((Dwarf_P_Fde) DW_DLV_BADADDR);
	}
	ptr = (char *) _dwarf_p_get_alloc(NULL, nbytes);
	if (ptr == NULL) {
	    _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
	    return ((Dwarf_P_Fde) DW_DLV_BADADDR);
	}
	memcpy(ptr, buff1, nbytes);
	break;

    default:
	break;
    }

    curinst->dfp_opcode = op;
    curinst->dfp_args = ptr;
    curinst->dfp_nbytes = nbytes;
    curinst->dfp_next = NULL;

    _dwarf_pro_add_to_fde(fde, curinst);
    return fde;
}
Example #28
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;
    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;
}
Example #29
0
int
dwarf_def_macro(Dwarf_P_Debug dbg,
		Dwarf_Unsigned line,
		char *macname, char *macvalue, Dwarf_Error * error)
{
    size_t len;
    size_t len2;
    size_t length_est;
    int res;
    int compose_error_type;

    if (dbg == NULL) {
	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
	return (DW_DLV_ERROR);
    }
    if (macname == 0) {
	_dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL);
	return (DW_DLV_ERROR);
    }
#ifdef TARG_IA64
    len = strlen(macname) + 1;
#else
    len = strlen(macname);
#endif
    if (len == 0) {
	_dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY);
	return (DW_DLV_ERROR);
    }
#ifdef TARG_IA64
    if (macvalue) {
        len2 = strlen(macvalue) + 1;
    } else {
        len2 = 0;
    }
    length_est = COMMAND_LEN + LINE_LEN + len + len2 + 1;       /* 1 */

#else
    len2 = macvalue ? strlen(macvalue) : 0;

    length_est = COMMAND_LEN + LINE_LEN + len + len2 + 1;
    if (len2 > 0) length_est += 1; /* add one for space */
#endif
    res = libdwarf_compose_begin(dbg, DW_MACINFO_define, length_est,
				 &compose_error_type);
    if (res != DW_DLV_OK) {
	_dwarf_p_error(NULL, error, compose_error_type);
	return (DW_DLV_ERROR);
    }
    res = libdwarf_compose_add_line(dbg, line, &compose_error_type);
    if (res != DW_DLV_OK) {
	_dwarf_p_error(NULL, error, compose_error_type);
	return (DW_DLV_ERROR);
    }
#ifdef TARG_IA64
    libdwarf_compose_add_string(dbg, macname, len);
    libdwarf_compose_add_string(dbg, " ", 1);
    if (macvalue) {
        libdwarf_compose_add_string(dbg, " ", 1);
	libdwarf_compose_add_string(dbg, macvalue, len2);
    }
#else
    if (macvalue) {
	libdwarf_compose_add_bytes(dbg, macname, len);
	libdwarf_compose_add_bytes(dbg, " ", 1);
	libdwarf_compose_add_string(dbg, macvalue, len2);
    }
    else {
        libdwarf_compose_add_string(dbg, macname, len);
    }
#endif
    
    res = libdwarf_compose_complete(dbg, &compose_error_type);
    if (res != DW_DLV_OK) {
	_dwarf_p_error(NULL, error, compose_error_type);
	return (DW_DLV_ERROR);
    }
    return DW_DLV_OK;
}
Example #30
0
Dwarf_Unsigned
dwarf_add_expr_gen (
    Dwarf_P_Expr	expr,
    Dwarf_Small		opcode,
    Dwarf_Unsigned	val1,
    Dwarf_Unsigned	val2,
    Dwarf_Error		*error
)
{
    char encode_buffer[2*ENCODE_SPACE_NEEDED]; /* 2* since used
		to concatenate 2 leb's below */
    char encode_buffer2[ENCODE_SPACE_NEEDED];
    int  res;
    Dwarf_P_Debug dbg = expr->ex_dbg;
	/* 
	    Give the buffer where the operands are first
	    going to be assembled the largest alignment.
	*/
    Dwarf_Unsigned	operand_buffer[10];

	/* 
	    Size of the byte stream buffer that needs 
	    to be memcpy-ed.
	*/
    int			operand_size;

	/* 
	    Points to the byte stream for the first operand,
	    and finally to the buffer that is memcp-ed into
	    the Dwarf_P_Expr_s struct.
	*/
    Dwarf_Small		*operand;

	/* Size of the byte stream for second operand. */
    int			operand2_size;

	/* Points to next byte to be written in Dwarf_P_Expr_s struct. */
    Dwarf_Small		*next_byte_ptr;

	/* Offset past the last byte written into Dwarf_P_Expr_s. */
    int			next_byte_offset;

    /* ***** BEGIN CODE ***** */

    if (expr == NULL) {
	_dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
	return(DW_DLV_NOCOUNT);
    }

    if (expr->ex_dbg == NULL) {
	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
	return(DW_DLV_NOCOUNT);
    }

    operand = NULL;
    operand_size = 0;

    switch (opcode) {
        case DW_OP_reg0 :
	case DW_OP_reg1 :
	case DW_OP_reg2 :
	case DW_OP_reg3 :
	case DW_OP_reg4 :
	case DW_OP_reg5 :
	case DW_OP_reg6 :
	case DW_OP_reg7 :
	case DW_OP_reg8 :
	case DW_OP_reg9 :
	case DW_OP_reg10 :
	case DW_OP_reg11 :
	case DW_OP_reg12 :
	case DW_OP_reg13 :
	case DW_OP_reg14 :
	case DW_OP_reg15 :
	case DW_OP_reg16 :
	case DW_OP_reg17 :
	case DW_OP_reg18 :
	case DW_OP_reg19 :
	case DW_OP_reg20 :
	case DW_OP_reg21 :
	case DW_OP_reg22 :
	case DW_OP_reg23 :
	case DW_OP_reg24 :
	case DW_OP_reg25 :
	case DW_OP_reg26 :
	case DW_OP_reg27 :
	case DW_OP_reg28 :
	case DW_OP_reg29 :
	case DW_OP_reg30 :
	case DW_OP_reg31 :
	    break;

	case DW_OP_breg0 :
	case DW_OP_breg1 :
	case DW_OP_breg2 :
	case DW_OP_breg3 :
	case DW_OP_breg4 :
	case DW_OP_breg5 :
	case DW_OP_breg6 :
	case DW_OP_breg7 :
	case DW_OP_breg8 :
	case DW_OP_breg9 :
	case DW_OP_breg10 :
	case DW_OP_breg11 :
	case DW_OP_breg12 :
	case DW_OP_breg13 :
	case DW_OP_breg14 :
	case DW_OP_breg15 :
	case DW_OP_breg16 :
	case DW_OP_breg17 :
	case DW_OP_breg18 :
	case DW_OP_breg19 :
	case DW_OP_breg20 :
	case DW_OP_breg21 :
	case DW_OP_breg22 :
	case DW_OP_breg23 :
	case DW_OP_breg24 :
	case DW_OP_breg25 :
	case DW_OP_breg26 :
	case DW_OP_breg27 :
	case DW_OP_breg28 :
	case DW_OP_breg29 :
	case DW_OP_breg30 :
	case DW_OP_breg31 :
	    res = _dwarf_pro_encode_signed_leb128_nm(val1, 
			&operand_size,encode_buffer,sizeof(encode_buffer));
	    if(res != DW_DLV_OK) {
	        _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
	        return(DW_DLV_NOCOUNT);
	    }
	    operand = (Dwarf_Small *)encode_buffer;
	    break;

        case DW_OP_regx :
	    res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
			encode_buffer, sizeof(encode_buffer));
	    if(res != DW_DLV_OK) {
	        _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
	        return(DW_DLV_NOCOUNT);
	    }
	    operand = (Dwarf_Small *)encode_buffer;
	    break;

	case DW_OP_lit0 :
	case DW_OP_lit1 :
	case DW_OP_lit2 :
	case DW_OP_lit3 :
	case DW_OP_lit4 :
	case DW_OP_lit5 :
	case DW_OP_lit6 :
	case DW_OP_lit7 :
	case DW_OP_lit8 :
	case DW_OP_lit9 :
	case DW_OP_lit10 :
	case DW_OP_lit11 :
	case DW_OP_lit12 :
	case DW_OP_lit13 :
	case DW_OP_lit14 :
	case DW_OP_lit15 :
	case DW_OP_lit16 :
	case DW_OP_lit17 :
	case DW_OP_lit18 :
	case DW_OP_lit19 :
	case DW_OP_lit20 :
	case DW_OP_lit21 :
	case DW_OP_lit22 :
	case DW_OP_lit23 :
	case DW_OP_lit24 :
	case DW_OP_lit25 :
	case DW_OP_lit26 :
	case DW_OP_lit27 :
	case DW_OP_lit28 :
	case DW_OP_lit29 :
	case DW_OP_lit30 :
	case DW_OP_lit31 :
	    break;
        
	case DW_OP_addr :
	    _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE);
	    return(DW_DLV_NOCOUNT);

	case DW_OP_const1u :
	case DW_OP_const1s :
            operand = (Dwarf_Small *)&operand_buffer[0];
	    WRITE_UNALIGNED(dbg,operand,&val1,sizeof(val1),1);
	    operand_size = 1;
	    break;

	case DW_OP_const2u :
	case DW_OP_const2s :
	    operand = (Dwarf_Small *)&operand_buffer[0];
	    WRITE_UNALIGNED(dbg,operand,&val1,sizeof(val1),2);
	    operand_size = 2;
	    break;

	case DW_OP_const4u :
	case DW_OP_const4s :
	    operand = (Dwarf_Small *)&operand_buffer[0];
	    WRITE_UNALIGNED(dbg,operand,&val1,sizeof(val1),4);
	    operand_size = 4;
	    break;

	case DW_OP_const8u :
	case DW_OP_const8s :
	    operand = (Dwarf_Small *)&operand_buffer[0];
	    WRITE_UNALIGNED(dbg,operand,&val1,sizeof(val1),8);
	    operand_size = 8;
	    break;

        case DW_OP_constu :
	    res = _dwarf_pro_encode_leb128_nm(val1, 
			&operand_size,
			encode_buffer, sizeof(encode_buffer));
	    if(res != DW_DLV_OK) {
	        _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
	        return(DW_DLV_NOCOUNT);
	    }
	    operand = (Dwarf_Small *)encode_buffer;
	    break;

	case DW_OP_consts :
	    res = _dwarf_pro_encode_signed_leb128_nm(val1, 
			&operand_size,
			encode_buffer, sizeof(encode_buffer));
	    if(res != DW_DLV_OK) {
	        _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
	        return(DW_DLV_NOCOUNT);
	    }
	    operand = (Dwarf_Small *)encode_buffer;
	    break;

	case DW_OP_fbreg :
	    res = _dwarf_pro_encode_signed_leb128_nm(val1, 
			&operand_size,
			encode_buffer, sizeof(encode_buffer));
	    if(res != DW_DLV_OK) {
	        _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
	        return(DW_DLV_NOCOUNT);
	    }
	    operand = (Dwarf_Small *)encode_buffer;
	    break;

	case DW_OP_bregx :
	    res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
			encode_buffer, sizeof(encode_buffer));
	    if(res != DW_DLV_OK) {
	        _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
	        return(DW_DLV_NOCOUNT);
	    }
	    operand = (Dwarf_Small *)encode_buffer;
		/* put this one directly into 'operand' at tail of
		   prev value
	 	*/
	    res =  _dwarf_pro_encode_signed_leb128_nm(val2, &operand2_size,
			((char *)operand)+operand_size, sizeof(encode_buffer2));
	    if(res != DW_DLV_OK) {
	        _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
	        return(DW_DLV_NOCOUNT);
	    }
	    operand_size += operand2_size;

	case DW_OP_dup :
	case DW_OP_drop :
	    break;

	case DW_OP_pick :
	    operand = (Dwarf_Small *)&operand_buffer[0];
	    WRITE_UNALIGNED(dbg,operand,(const void *)val1,
			sizeof(val1),1);
	    operand_size = 1;
	    break;

	case DW_OP_over :
	case DW_OP_swap :
	case DW_OP_rot :
	case DW_OP_deref :
	case DW_OP_xderef :
            break;

	case DW_OP_deref_size :
	case DW_OP_xderef_size :
	    operand = (Dwarf_Small *)&operand_buffer[0];
	    WRITE_UNALIGNED(dbg,operand,(const void *)val1,
			sizeof(val1),1);
	    operand_size = 1;
	    break;

        case DW_OP_abs :
	case DW_OP_and :
	case DW_OP_div :
	case DW_OP_minus :
	case DW_OP_mod :
	case DW_OP_mul :
	case DW_OP_neg :
	case DW_OP_not :
	case DW_OP_or :
	case DW_OP_plus :
	    break;

	case DW_OP_plus_uconst :
	    res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
			encode_buffer, sizeof(encode_buffer));
	    if(res != DW_DLV_OK) {
	        _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
	        return(DW_DLV_NOCOUNT);
	    }
	    operand = (Dwarf_Small *)encode_buffer;
	    break;

	case DW_OP_shl :
	case DW_OP_shr :
	case DW_OP_shra :
	case DW_OP_xor :
	    break;

	case DW_OP_le :
	case DW_OP_ge :
	case DW_OP_eq :
	case DW_OP_lt :
	case DW_OP_gt :
	case DW_OP_ne :
	    break;

	case DW_OP_skip :
	case DW_OP_bra :
            /* FIX: unhandled! OP_bra, OP_skip! */
	    _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE);
	    return(DW_DLV_NOCOUNT);

	case DW_OP_piece :
	    res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
			encode_buffer, sizeof(encode_buffer));
	    if(res != DW_DLV_OK) {
	        _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
	        return(DW_DLV_NOCOUNT);
	    }
	    operand = (Dwarf_Small *)encode_buffer;
	    break;

	case DW_OP_nop :
	    break;

	default :
	    _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE);
	    return(DW_DLV_NOCOUNT);
    }

    next_byte_offset = expr->ex_next_byte_offset + operand_size + 1;

    if (next_byte_offset > MAXIMUM_LOC_EXPR_LENGTH) {
	_dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
	return(DW_DLV_NOCOUNT);
    }

    next_byte_ptr = &(expr->ex_byte_stream[0]) + expr->ex_next_byte_offset;

    *next_byte_ptr = opcode;
    next_byte_ptr++;
    memcpy(next_byte_ptr, operand, operand_size);

    expr->ex_next_byte_offset = next_byte_offset;
    return(next_byte_offset);
}