Example #1
0
/*
    This function takes an Dwarf_Arange,
    and returns the offset of the CU header
    in the compilation-unit that the
    arange belongs to.  Returns DW_DLV_ERROR
    on error.
*/
int
dwarf_get_arange_cu_header_offset(Dwarf_Arange arange,
    Dwarf_Off * cu_header_offset_returned,
    Dwarf_Error * error)
{
    if (arange == NULL) {
        _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
        return (DW_DLV_ERROR);
    }
    *cu_header_offset_returned = arange->ar_info_offset;
    return DW_DLV_OK;
}
Example #2
0
/*
	Given a pubnames entry (or other like section entry)
	return thru the ret_off pointer the
	global offset of the DIE for this entry.
	The global offset is the offset within the .debug_info
	section as a whole.
*/
int
dwarf_global_die_offset (
    Dwarf_Global	global,
    Dwarf_Off          *ret_off,
    Dwarf_Error		*error
)
{
    if (global == NULL) {
	_dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); 
	return(DW_DLV_ERROR);
    }

    if (global->gl_context == NULL) {
	_dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL);
	return(DW_DLV_ERROR);
    }

    *ret_off = (global->gl_named_die_offset_within_cu + 
		global->gl_context->pu_offset_of_cu_header);
    return DW_DLV_OK;
}
Example #3
0
int
dwarf_weakname(Dwarf_Weak weak_in, char **ret_name, Dwarf_Error * error)
{
    Dwarf_Global weak = (Dwarf_Global) weak_in;

    if (weak == NULL) {
	_dwarf_error(NULL, error, DW_DLE_WEAK_NULL);
	return (DW_DLV_ERROR);
    }
    *ret_name = (char *) (weak->gl_name);
    return DW_DLV_OK;
}
Example #4
0
/*  DWARF defines DW_TAG_hi_user as 0xffff so no tag should be
    over 16 bits.  */
int
dwarf_get_abbrev_tag(Dwarf_Abbrev abbrev,
    Dwarf_Half * returned_tag, Dwarf_Error * error)
{
    if (abbrev == NULL) {
        _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
        return (DW_DLV_ERROR);
    }

    *returned_tag = abbrev->ab_tag;
    return (DW_DLV_OK);
}
Example #5
0
int
dwarf_formflag(Dwarf_Attribute attr,
               Dwarf_Bool* ret_bool,
               Dwarf_Error * error)
{
  Dwarf_CU_Context cu_context;

  if (attr == NULL) {
    _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
    return (DW_DLV_ERROR);
  }

  cu_context = attr->ar_cu_context;
  if (cu_context == NULL) {
    _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
    return (DW_DLV_ERROR);
  }

  if (cu_context->cc_dbg == NULL) {
    _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
    return (DW_DLV_ERROR);
  }

  if (attr->ar_attribute_form == DW_FORM_flag) {
    *ret_bool = (*(Dwarf_Small *) attr->ar_debug_info_ptr != 0);
    return (DW_DLV_OK);
  }

  /*
   * DWARF4: the attribute is implicitly indicated as present, and no value is
   * encoded in the debugging information entry itself.
   */
  if (attr->ar_attribute_form == DW_FORM_flag_present) {
    *ret_bool = 1;
    return (DW_DLV_OK);
  }

  _dwarf_error(cu_context->cc_dbg, error, DW_DLE_ATTR_FORM_BAD);
  return (DW_DLV_ERROR);
}
/* Read in the common cie/fde prefix, including reading
 * the cie-value which shows which this is: cie or fde.
 * */
int
dwarf_read_cie_fde_prefix(Dwarf_Debug dbg,
			  Dwarf_Small * frame_ptr_in,
			  Dwarf_Small * section_ptr_in,
			  Dwarf_Unsigned section_index_in,
			  Dwarf_Unsigned section_length_in,
			  struct cie_fde_prefix_s *data_out,
			  Dwarf_Error * error)
{
    Dwarf_Unsigned length = 0;
    int local_length_size = 0;
    int local_extension_size = 0;
    Dwarf_Small *frame_ptr = frame_ptr_in;
    Dwarf_Small *cie_ptr_addr = 0;
    Dwarf_Unsigned cie_id = 0;

    /* READ_AREA_LENGTH updates frame_ptr for consumed bytes */
    READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
		     frame_ptr, local_length_size,
		     local_extension_size);

    if (length % local_length_size != 0) {
	_dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);
	return (DW_DLV_ERROR);
    }

    if (length == 0) {
	/* nul bytes at end of section, seen at end of egcs eh_frame
	   sections (in a.out). Take this as meaning no more CIE/FDE
	   data. We should be very close to end of section. */
	return DW_DLV_NO_ENTRY;
    }

    cie_ptr_addr = frame_ptr;
    READ_UNALIGNED(dbg, cie_id, Dwarf_Unsigned,
		   frame_ptr, local_length_size);
    SIGN_EXTEND(cie_id, local_length_size);
    frame_ptr += local_length_size;

    data_out->cf_start_addr = frame_ptr_in;
    data_out->cf_addr_after_prefix = frame_ptr;

    data_out->cf_length = length;
    data_out->cf_local_length_size = local_length_size;
    data_out->cf_local_extension_size = local_extension_size;
    data_out->cf_cie_id = cie_id;
    data_out->cf_cie_id_addr = cie_ptr_addr;
    data_out->cf_section_ptr = section_ptr_in;
    data_out->cf_section_index = section_index_in;
    data_out->cf_section_length = section_length_in;
    return DW_DLV_OK;
}
Example #7
0
int
dwarf_get_abbrev_code(Dwarf_Abbrev abbrev,
		      Dwarf_Unsigned * returned_code,
		      Dwarf_Error * error)
{
    if (abbrev == NULL) {
	_dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
	return (DW_DLV_ERROR);
    }

    *returned_code = abbrev->ab_code;
    return (DW_DLV_OK);
}
Example #8
0
int
dwarf_funcname(Dwarf_Func func_in, char **ret_name, Dwarf_Error * error)
{
    Dwarf_Global func = (Dwarf_Global) func_in;

    if (func == NULL) {
        _dwarf_error(NULL, error, DW_DLE_FUNC_NULL);
        return (DW_DLV_ERROR);
    }

    *ret_name = (char *) (func->gl_name);
    return DW_DLV_OK;
}
Example #9
0
int
dwarf_formexprloc(Dwarf_Attribute attr,
    Dwarf_Unsigned * return_exprlen,
    Dwarf_Ptr  * block_ptr,
    Dwarf_Error * error)
{
    Dwarf_Debug dbg = 0;
    Dwarf_CU_Context cu_context = 0;

    int res  = get_attr_dbg(&dbg,&cu_context,attr,error);
    if (res != DW_DLV_OK) {
        return res;
    }
    if (dbg == NULL) {
        _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
        return (DW_DLV_ERROR);
    }
    if (attr->ar_attribute_form == DW_FORM_exprloc ) {
        Dwarf_Die die = 0;
        Dwarf_Word leb_len = 0;
        Dwarf_Unsigned exprlen =
            (_dwarf_decode_u_leb128(attr->ar_debug_ptr, &leb_len));
        Dwarf_Small * addr = attr->ar_debug_ptr;
        /*  Is the block entirely in the section, or is
            there bug somewhere? */
        die = attr->ar_die;
        if (_dwarf_reference_outside_section(die,
            (Dwarf_Small *)addr, ((Dwarf_Small *)addr)+exprlen +leb_len)) {
            _dwarf_error(dbg, error,DW_DLE_ATTR_OUTSIDE_SECTION);
            return DW_DLV_ERROR;
        }
        *return_exprlen = exprlen;
        *block_ptr = addr + leb_len;
        return DW_DLV_OK;

    }
    _dwarf_error(dbg, error, DW_DLE_ATTR_EXPRLOC_FORM_BAD);
    return (DW_DLV_ERROR);
}
Example #10
0
/*
	Given a pubnames entry (or other like section entry)
	return thru the ret_name pointer
	a pointer to the string which is the entry name.
	
*/
int
dwarf_globname (
    Dwarf_Global	glob,
    char **             ret_name,
    Dwarf_Error		*error
)
{
    if (glob == NULL)
	{_dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); return(DW_DLV_ERROR);}

    *ret_name = (char *)(glob->gl_name);
    return DW_DLV_OK;
}
Example #11
0
int
dwarf_get_abbrev_children_flag(Dwarf_Abbrev abbrev,
			       Dwarf_Signed * returned_flag,
			       Dwarf_Error * error)
{
    if (abbrev == NULL) {
	_dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
	return (DW_DLV_ERROR);
    }

    *returned_flag = abbrev->ab_has_child;
    return (DW_DLV_OK);
}
Example #12
0
int
dwarf_typename(Dwarf_Type type_in, char **ret_name, Dwarf_Error * error)
{
    Dwarf_Global type = (Dwarf_Global) type_in;

    if (type == NULL) {
	_dwarf_error(NULL, error, DW_DLE_TYPE_NULL);
	return (DW_DLV_ERROR);
    }

    *ret_name = (char *) (type->gl_name);
    return DW_DLV_OK;
}
Example #13
0
int
dwarf_varname(Dwarf_Var var_in, char **ret_varname, Dwarf_Error * error)
{
    Dwarf_Global var = (Dwarf_Global) var_in;

    if (var == NULL) {
	_dwarf_error(NULL, error, DW_DLE_VAR_NULL);
	return (DW_DLV_ERROR);
    }

    *ret_varname = (char *) (var->gl_name);
    return DW_DLV_OK;
}
Example #14
0
int
dwarf_formexprloc(Dwarf_Attribute attr,
    Dwarf_Unsigned * return_exprlen, 
    Dwarf_Ptr  * block_ptr,
    Dwarf_Error * error)
{
    Dwarf_Debug dbg = 0;
    Dwarf_CU_Context cu_context = 0;

    if (attr == NULL) {
        _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
        return (DW_DLV_ERROR);
    }

    cu_context = attr->ar_cu_context;
    if (cu_context == NULL) {
        _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
        return (DW_DLV_ERROR);
    }

    dbg = cu_context->cc_dbg;
    if (dbg == NULL) {
        _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
        return (DW_DLV_ERROR);
    }

    if (attr->ar_attribute_form == DW_FORM_udata ) {
        Dwarf_Unsigned exprlen =
            (_dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL));
        Dwarf_Small * addr = attr->ar_debug_info_ptr;
        *return_exprlen = exprlen;
        *block_ptr = addr + exprlen;
        return DW_DLV_OK;

    }
    _dwarf_error(dbg, error, DW_DLE_ATTR_EXPRLOC_FORM_BAD);
    return (DW_DLV_ERROR);
}
Example #15
0
static int
_dwarf_formsig8_internal(Dwarf_Attribute attr,
    int formexpected,
    int formerrnum,
    Dwarf_Sig8 * returned_sig_bytes,
    Dwarf_Error*     error)
{
    Dwarf_Debug dbg = 0;
    Dwarf_Unsigned field_end_offset = 0;
    Dwarf_CU_Context cu_context = 0;
    Dwarf_Small *dataptr = 0;

    int res  = get_attr_dbg(&dbg,&cu_context,attr,error);
    if (res != DW_DLV_OK) {
        return res;
    }

    if (attr->ar_attribute_form != formexpected ) {
        _dwarf_error(dbg, error, formerrnum);
        return (DW_DLV_ERROR);
    }

    dataptr = cu_context->cc_is_info? dbg->de_debug_info.dss_data:
        dbg->de_debug_types.dss_data;

    field_end_offset = attr->ar_debug_ptr + sizeof(Dwarf_Sig8) -
        (dataptr + cu_context->cc_debug_offset);
    /* Check that offset is within current cu portion of .debug_info. */
    if (field_end_offset > cu_context->cc_length +
        cu_context->cc_length_size + cu_context->cc_extension_size) {
        _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD);
        return (DW_DLV_ERROR);
    }

    memcpy(returned_sig_bytes, attr->ar_debug_ptr,
        sizeof(Dwarf_Sig8));
    return DW_DLV_OK;
}
Example #16
0
int
dwarf_get_str(Dwarf_Debug dbg,
              Dwarf_Off offset,
              char **string,
              Dwarf_Signed * returned_str_len, Dwarf_Error * error)
{
    int res = DW_DLV_ERROR;

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

    if (offset == dbg->de_debug_str.dss_size) {
        /* Normal (if we've iterated thru the set of strings using
           dwarf_get_str and are at the end). */
        return DW_DLV_NO_ENTRY;
    }
    if (offset > dbg->de_debug_str.dss_size) {
        _dwarf_error(dbg, error, DW_DLE_DEBUG_STR_OFFSET_BAD);
        return (DW_DLV_ERROR);
    }

    if (string == NULL) {
        _dwarf_error(dbg, error, DW_DLE_STRING_PTR_NULL);
        return (DW_DLV_ERROR);
    }

    res = _dwarf_load_section(dbg, &dbg->de_debug_str,error);
    if (res != DW_DLV_OK) {
        return res;
    }

    *string = (char *) dbg->de_debug_str.dss_data + offset;

    *returned_str_len = (strlen(*string));
    return DW_DLV_OK;
}
Example #17
0
int
dwarf_lineoff(Dwarf_Line line,
	      Dwarf_Signed * ret_lineoff, Dwarf_Error * error)
{
    if (line == NULL || ret_lineoff == 0) {
	_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
	return (DW_DLV_ERROR);
    }

    *ret_lineoff =
	(line->li_addr_line.li_l_data.li_column ==
	 0 ? -1 : line->li_addr_line.li_l_data.li_column);
    return DW_DLV_OK;
}
Example #18
0
int
_dwarf_extract_string_offset_via_str_offsets(Dwarf_Debug dbg,
    Dwarf_Small *info_data_ptr,
    Dwarf_Half   attrnum,
    Dwarf_Half   attrform,
    Dwarf_CU_Context cu_context,
    Dwarf_Unsigned *str_sect_offset_out,
    Dwarf_Error *error)
{
    Dwarf_Unsigned offsettostr= 0;
    Dwarf_Unsigned offset_base = 0;
    Dwarf_Word leb_len = 0;
    Dwarf_Unsigned index_to_offset_entry = 0;
    Dwarf_Unsigned offsetintable = 0;
    Dwarf_Unsigned end_offsetintable = 0;
    int res = 0;

    res = _dwarf_load_section(dbg, &dbg->de_debug_str_offsets,error);
    if (res != DW_DLV_OK) {
        return res;
    }
    index_to_offset_entry = (_dwarf_decode_u_leb128(info_data_ptr, &leb_len));
    /*  DW_FORM_GNU_str_index has no 'base' value.
        DW_FORM_strx has a base value
        for the offset table */
    if( attrform == DW_FORM_strx) {
        res = _dwarf_get_string_base_attr_value(dbg,cu_context,
            &offset_base,error);
        if (res != DW_DLV_OK) {
            return res;
        }
    }

    offsetintable = (index_to_offset_entry*cu_context->cc_length_size )
        + offset_base;
    end_offsetintable = offsetintable + cu_context->cc_length_size;
    /* The offsets table is a series of offset-size entries. */
    if ((end_offsetintable) >= dbg->de_debug_str_offsets.dss_size ) {
        _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD);
        return (DW_DLV_ERROR);
    }

    /* Now read the string offset from the offset table. */
    READ_UNALIGNED(dbg,offsettostr,Dwarf_Unsigned,
        dbg->de_debug_str_offsets.dss_data + offsetintable,
        cu_context->cc_length_size);
    *str_sect_offset_out = offsettostr;
    return DW_DLV_OK;
}
Example #19
0
int
dwarf_formaddr(Dwarf_Attribute attr,
    Dwarf_Addr * return_addr, Dwarf_Error * error)
{
    Dwarf_Debug dbg = 0;
    Dwarf_Addr ret_addr = 0;
    Dwarf_CU_Context cu_context = 0;

    int res  = get_attr_dbg(&dbg,&cu_context,attr,error);
    if (res != DW_DLV_OK) {
        return res;
    }
    if (attr->ar_attribute_form == DW_FORM_GNU_addr_index ||
        attr->ar_attribute_form == DW_FORM_addrx) {
        Dwarf_Addr addr_out = 0;
        res = _dwarf_extract_address_from_debug_addr(dbg,
            cu_context,
            attr->ar_debug_ptr,
            &addr_out,
            error);

        if (res != DW_DLV_OK) {
            return res;
        }
        *return_addr = addr_out;
        return (DW_DLV_OK);
    }
    if (attr->ar_attribute_form == DW_FORM_addr
        /*  || attr->ar_attribute_form == DW_FORM_ref_addr Allowance of
            DW_FORM_ref_addr was a mistake. The value returned in that
            case is NOT an address it is a global debug_info offset (ie,
            not CU-relative offset within the CU in debug_info). The
            Dwarf document refers to it as an address (misleadingly) in
            sec 6.5.4 where it describes the reference form. It is
            address-sized so that the linker can easily update it, but
            it is a reference inside the debug_info section. No longer
            allowed. */
        ) {

        READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr,
            attr->ar_debug_ptr,
            cu_context->cc_address_size);
        *return_addr = ret_addr;
        return (DW_DLV_OK);
    }
    _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
    return (DW_DLV_ERROR);
}
Example #20
0
/*  Convert an offset within the local CU into a section-relative
    debug_info (or debug_types) offset.
    See dwarf_global_formref() and dwarf_formref()
    for additional information on conversion rules.
*/
int
dwarf_convert_to_global_offset(Dwarf_Attribute attr,
    Dwarf_Off offset, Dwarf_Off * ret_offset, Dwarf_Error * error)
{
    Dwarf_Debug dbg = 0;
    Dwarf_CU_Context cu_context = 0;
    int res = 0;

    res  = get_attr_dbg(&dbg,&cu_context,attr,error);
    if (res != DW_DLV_OK) {
        return res;
    }
    switch (attr->ar_attribute_form) {
    case DW_FORM_ref1:
    case DW_FORM_ref2:
    case DW_FORM_ref4:
    case DW_FORM_ref8:
    case DW_FORM_ref_udata:
        /*  It is a cu-local offset. Convert to section-global. */
        /*  It would be nice to put some code to check
            legality of the offset */
        /*  cc_debug_offset always has any DWP Package File
            offset included (when the cu_context created)
            so there is no extra work for DWP.

        /*  globalize the offset */
        offset += cu_context->cc_debug_offset;

        break;

    case DW_FORM_ref_addr:
        /*  This offset is defined to be debug_info global already, so
            use this value unaltered.

            Since a DWP package file is not relocated there
            is no way that this reference offset to an address in
            any other CU can be correct for a DWP Package File offset
            */
        break;

    default:
        _dwarf_error(dbg, error, DW_DLE_BAD_REF_FORM);
        return (DW_DLV_ERROR);
    }

    *ret_offset = (offset);
    return DW_DLV_OK;
}
Example #21
0
void
_dwarf_error_mv_s_to_t(Dwarf_Debug dbgs,Dwarf_Error *errs,
    Dwarf_Debug dbgt,Dwarf_Error *errt)
{
    if(dbgs == dbgt) {
        if(errs != errt) {
            Dwarf_Error ers = *errs;
            *errs = 0;
            *errt = ers;
        }
    } else {
        int errno = dwarf_errno(*errs);
        dwarf_dealloc(dbgs,*errs, DW_DLA_ERROR);
        *errs = 0;
        _dwarf_error(dbgt,errt, errno);
    }
}
Example #22
0
/*  Richard Henderson: The operand is an absolute
    address.  The first byte of the value
    is an encoding length: 0 2 4 or 8.  If zero
    it means the following is address-size.
    The address then follows immediately for
    that number of bytes. */
static int
read_encoded_addr(Dwarf_Small *loc_ptr, Dwarf_Debug dbg,
   Dwarf_Unsigned * val_out, 
   int * len_out,
   Dwarf_Error *error)
{
    int totallen = 0;
    int oplen = 0;
    int len = 0;
    Dwarf_Small op = *loc_ptr;
    Dwarf_Unsigned operand = 0;
    len++;
    if(op == 0) {
        /* FIXME: should be CU specific. */
        op = dbg->de_pointer_size;
    }
    switch(op) {
    case 1:
         *val_out = *loc_ptr;
         len++;
         break;
        
    case 2:
         READ_UNALIGNED(dbg, operand, Dwarf_Unsigned, loc_ptr, 2);
         *val_out = operand;
         len +=2;
         break;
    case 4:
         READ_UNALIGNED(dbg, operand, Dwarf_Unsigned, loc_ptr, 4);
         *val_out = operand;
         len +=4;
         break;
    case 8:
         READ_UNALIGNED(dbg, operand, Dwarf_Unsigned, loc_ptr, 8);
         *val_out = operand;
         len +=8;
         break;
    default:
         /* We do not know how much to read. */
        _dwarf_error(dbg, error, DW_DLE_GNU_OPCODE_ERROR);
         return DW_DLV_ERROR;
    };
    *len_out = len;
    return DW_DLV_OK;
}
Example #23
0
int
_dwarf_loc_block_sanity_check(Dwarf_Debug dbg,
    Dwarf_Block_c *loc_block,Dwarf_Error* error)
{
    if (loc_block->bl_from_loclist) {
        Dwarf_Small *loc_ptr = 0;
        Dwarf_Unsigned loc_len = 0;
        Dwarf_Small *end_ptr = 0;

        loc_ptr = loc_block->bl_data;
        loc_len = loc_block->bl_len;
        end_ptr =  dbg->de_debug_loc.dss_size +
            dbg->de_debug_loc.dss_data;
        if ((loc_ptr +loc_len) > end_ptr) {
            _dwarf_error(dbg,error,DW_DLE_DEBUG_LOC_SECTION_SHORT);
            return DW_DLV_ERROR;
        }
    }
    return DW_DLV_OK;
}
Example #24
0
/* New for DWARF4, entries may have segment information. 
   *segment is only meaningful if *segment_entry_size is non-zero. */
int 
dwarf_get_arange_info_b(Dwarf_Arange arange,
    Dwarf_Unsigned*  segment,
    Dwarf_Unsigned*  segment_entry_size,
    Dwarf_Addr    * start,
    Dwarf_Unsigned* length,
    Dwarf_Off     * cu_die_offset, 
    Dwarf_Error   * error)
{   
    if (arange == NULL) {
        _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
        return (DW_DLV_ERROR);
    }
    
    if(segment != NULL) {
        *segment = arange->ar_segment_selector;
    }
    if(segment_entry_size != NULL) {
        *segment_entry_size = arange->ar_segment_selector_size;
    }
    if (start != NULL)
        *start = arange->ar_address;
    if (length != NULL)
        *length = arange->ar_length;
    if (cu_die_offset != NULL) {
        Dwarf_Debug dbg = arange->ar_dbg;
        Dwarf_Off offset = arange->ar_info_offset;

        /* This applies to debug_info only, not to debug_types. */
        if (!dbg->de_debug_info.dss_data) {
            int res = _dwarf_load_debug_info(dbg, error);
            if (res != DW_DLV_OK) {
                return res;
            }
        }
        *cu_die_offset =
            offset + _dwarf_length_of_cu_header(dbg, offset,true);
    }
    return (DW_DLV_OK);
}   
Example #25
0
static int
context_is_cu_not_tu(Dwarf_CU_Context context,
    Dwarf_Bool *r,Dwarf_Error *err)
{
    Dwarf_Debug dbg = 0;
    if(context->cc_unit_type == DW_UT_type) {
        *r =FALSE;
        return DW_DLV_OK;
    }
    if(context->cc_unit_type == DW_UT_compile) {
        *r = TRUE;
        return DW_DLV_OK;
    }
    if(context->cc_unit_type == DW_UT_partial) {
        *r = TRUE;
        return DW_DLV_OK;
    }
    /* This should be impossible */
    dbg = context->cc_dbg;
    _dwarf_error(dbg,err, DW_DLE_NO_TIED_FILE_AVAILABLE);
    return DW_DLV_ERROR;
}
Example #26
0
int
dwarf_get_locdesc_entry_c(Dwarf_Loc_Head_c loclist_head,
   Dwarf_Unsigned   index,
   Dwarf_Small    * lle_value_out, /* identifies type of loclist entry*/
   Dwarf_Addr     * lowpc_out,
   Dwarf_Addr     * hipc_out,
   Dwarf_Unsigned * loclist_count_out,

   /* Returns pointer to the specific locdesc of the index; */
   Dwarf_Locdesc_c* locdesc_entry_out,
   Dwarf_Small    * loclist_source_out, /* 0,1, or 2 */
   Dwarf_Unsigned * expression_offset_out,
   Dwarf_Unsigned * locdesc_offset_out,
   Dwarf_Error    * error)
{
    Dwarf_Locdesc_c descs_base =  0;
    Dwarf_Locdesc_c desc =  0;
    Dwarf_Unsigned desc_count = 0;
    Dwarf_Debug dbg;

    desc_count = loclist_head->ll_locdesc_count;
    descs_base  = loclist_head->ll_locdesc;
    dbg = loclist_head->ll_dbg;
    if (index >= desc_count) {
        _dwarf_error(dbg, error, DW_DLE_LOCLIST_INDEX_ERROR);
        return (DW_DLV_ERROR);
    }
    desc = descs_base + index;
    *lle_value_out = desc->ld_lle_value;
    *lowpc_out = desc->ld_lopc;
    *hipc_out = desc->ld_hipc;
    *loclist_count_out = desc->ld_cents;
    *locdesc_entry_out = desc;
    *loclist_source_out = desc->ld_from_loclist;
    *expression_offset_out = desc->ld_section_offset;
    *locdesc_offset_out = desc->ld_locdesc_offset;
    return DW_DLV_OK;
}
Example #27
0
/*  Convert an offset within the local CU into a section-relative
    debug_info offset. See dwarf_global_formref() and dwarf_formref()
    for additional information on conversion rules.
*/
int
dwarf_convert_to_global_offset(Dwarf_Attribute attr,
    Dwarf_Off offset, Dwarf_Off * ret_offset, Dwarf_Error * error)
{
    Dwarf_Debug dbg = 0;
    Dwarf_CU_Context cu_context = 0;
  
    int res  = get_attr_dbg(&dbg,&cu_context,attr,error);
    if (res != DW_DLV_OK) { 
        return res;
    } 

    switch (attr->ar_attribute_form) {
    case DW_FORM_ref1:
    case DW_FORM_ref2:
    case DW_FORM_ref4:
    case DW_FORM_ref8:
    case DW_FORM_ref_udata:
        /*  It would be nice to put some code to check 
            legality of the offset */
        /*  globalize the offset */
        offset += cu_context->cc_debug_offset;
        break;

    case DW_FORM_ref_addr:
        /*  This offset is defined to be debug_info global already, so
            use this value unaltered. */
        break;

    default:
        _dwarf_error(dbg, error, DW_DLE_BAD_REF_FORM);
        return (DW_DLV_ERROR);
    }

    *ret_offset = (offset);
    return DW_DLV_OK;
}
Example #28
0
/*
    This function takes an Dwarf_Arange,
    and returns the offset of the first
    die in the compilation-unit that the
    arange belongs to.  Returns DW_DLV_ERROR
    on error.
*/
int
dwarf_get_cu_die_offset(Dwarf_Arange arange,
    Dwarf_Off * returned_offset,
    Dwarf_Error * error)
{
    Dwarf_Debug dbg;
    Dwarf_Off offset = 0;

    if (arange == NULL) {
        _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
        return (DW_DLV_ERROR);
    }
    dbg = arange->ar_dbg;
    offset = arange->ar_info_offset;
    if (!dbg->de_debug_info.dss_data) {
        int res = _dwarf_load_debug_info(dbg, error);

        if (res != DW_DLV_OK) {
            return res;
        }
    }
    *returned_offset = offset + _dwarf_length_of_cu_header(dbg, offset);
    return DW_DLV_OK;
}
Example #29
0
/*  This function takes an Dwarf_Arange,
    and returns the offset of the CU header
    in the compilation-unit that the
    arange belongs to.  Returns DW_DLV_ERROR
    on error.   
    Ensures .debug_info loaded so
    the cu_offset is meaningful.  */
int
dwarf_get_arange_cu_header_offset(Dwarf_Arange arange,
    Dwarf_Off * cu_header_offset_returned,
    Dwarf_Error * error)
{
    Dwarf_Debug dbg = 0;
    if (arange == NULL) {
        _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
        return (DW_DLV_ERROR);
    }
    dbg = arange->ar_dbg;
    /* This applies to debug_info only, not to debug_types. */
    /*  Like dwarf_get_arange_info this ensures debug_info loaded:
        the cu_header is in debug_info and will be used else
        we would not call dwarf_get_arange_cu_header_offset. */
    if (!dbg->de_debug_info.dss_data) {
        int res = _dwarf_load_debug_info(dbg, error);
        if (res != DW_DLV_OK) {
            return res;
        }
    }
    *cu_header_offset_returned = arange->ar_info_offset;
    return DW_DLV_OK;
}
Example #30
0
int
dwarf_formblock(Dwarf_Attribute attr,
    Dwarf_Block ** return_block, Dwarf_Error * error)
{
    Dwarf_CU_Context cu_context = 0;
    Dwarf_Debug dbg = 0;
    Dwarf_Unsigned length = 0;
    Dwarf_Small *data = 0;
    Dwarf_Word leb128_length = 0;
    Dwarf_Block *ret_block = 0;
    Dwarf_Small *dataptr = 0;

    int res  = get_attr_dbg(&dbg,&cu_context,attr,error);
    if (res != DW_DLV_OK) {
        return res;
    }
    switch (attr->ar_attribute_form) {

    case DW_FORM_block1:
        length = *(Dwarf_Small *) attr->ar_debug_ptr;
        data = attr->ar_debug_ptr + sizeof(Dwarf_Small);
        break;

    case DW_FORM_block2:
        READ_UNALIGNED(dbg, length, Dwarf_Unsigned,
            attr->ar_debug_ptr, sizeof(Dwarf_Half));
        data = attr->ar_debug_ptr + sizeof(Dwarf_Half);
        break;

    case DW_FORM_block4:
        READ_UNALIGNED(dbg, length, Dwarf_Unsigned,
            attr->ar_debug_ptr, sizeof(Dwarf_ufixed));
        data = attr->ar_debug_ptr + sizeof(Dwarf_ufixed);
        break;

    case DW_FORM_block:
        length = _dwarf_decode_u_leb128(attr->ar_debug_ptr,
            &leb128_length);
        data = attr->ar_debug_ptr + leb128_length;
        break;

    default:
        _dwarf_error(cu_context->cc_dbg, error, DW_DLE_ATTR_FORM_BAD);
        return (DW_DLV_ERROR);
    }

    /* Check that block lies within current cu in .debug_info. */
    dataptr = cu_context->cc_is_info? dbg->de_debug_info.dss_data:
        dbg->de_debug_types.dss_data;

    if (attr->ar_debug_ptr + length >=
        dataptr + cu_context->cc_debug_offset +
        cu_context->cc_length + cu_context->cc_length_size +
        cu_context->cc_extension_size) {
        _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD);
        return (DW_DLV_ERROR);
    }

    ret_block = (Dwarf_Block *) _dwarf_get_alloc(dbg, DW_DLA_BLOCK, 1);
    if (ret_block == NULL) {
        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
        return (DW_DLV_ERROR);
    }

    ret_block->bl_len = length;
    ret_block->bl_data = (Dwarf_Ptr) data;
    ret_block->bl_from_loclist = 0;
    ret_block->bl_section_offset = data - dataptr;


    *return_block = ret_block;
    return (DW_DLV_OK);
}