Example #1
0
static int
die_mem_offset(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name,
    Dwarf_Unsigned *valp, int req)
{
	Dwarf_Attribute attr;
	Dwarf_Locdesc *loc;
	Dwarf_Signed locnum;

	if ((attr = die_attr(dw, die, name, req)) == NULL)
		return (0); /* die_attr will terminate for us if necessary */

	if (dwarf_loclist(attr, &loc, &locnum, &dw->dw_err) != DW_DLV_OK) {
		terminate("die %llu: failed to get mem offset location list\n",
		    die_off(dw, die));
	}

	dwarf_dealloc(dw->dw_dw, attr, DW_DLA_ATTR);

	if (locnum != 1 || loc->ld_s->lr_atom != DW_OP_plus_uconst) {
		terminate("die %llu: cannot parse member offset\n",
		    die_off(dw, die));
	}

	*valp = loc->ld_s->lr_number;

	dwarf_dealloc(dw->dw_dw, loc->ld_s, DW_DLA_LOC_BLOCK);
	dwarf_dealloc(dw->dw_dw, loc, DW_DLA_LOCDESC);

	return (1);
}
Example #2
0
static void DC_get_location_attr_value(Dwarf_Attribute at, DC_location *dcl){
  /*
   * It is assumed that at has a block form, and is a location list
   * so this won't fail.  Caller is responsible for checking.
   */

  Dwarf_Locdesc *locationList;
  Dwarf_Signed listLength;
  Dwarf_Error error;
  int frameRel = 0;
  long offset = 0;
  int i;
  int ret = dwarf_loclist( at, &locationList, &listLength, &error );
  if( ret != DW_DLV_OK ){
    return;
  }

  /*Get the location info*/
  decode_location(locationList,listLength,&(dcl->offset),NULL,&(dcl->isFrameOffset));

  /*Clean up*/
  for( i = 0; i < listLength; ++i){
    dwarf_dealloc(d,locationList[i].ld_s,DW_DLA_LOC_BLOCK);               
  }
  dwarf_dealloc(d,locationList,DW_DLA_LOCDESC);               
  
}
/*
	Return DW_DLV_OK if handling this went ok.
*/
static int
handle_attr_locdesc(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Half attrnum,
		    Dwarf_Error * perr)
{
    int retval = DW_DLV_OK;
    Dwarf_Attribute attr;
    Dwarf_Locdesc *llbuf;
    Dwarf_Signed i;
    Dwarf_Off offset;
    Dwarf_Loc *locp;
    unsigned int entindx;
    int res;
    int ares;


    ares = dwarf_attr(die, attrnum, &attr, perr);
    if (ares == DW_DLV_OK) {
	Dwarf_Half form;
	int fres = dwarf_whatform(attr, &form, perr);

	if (fres == DW_DLV_OK) {
	    switch (form) {
	    case DW_FORM_block1:
	    case DW_FORM_block2:
	    case DW_FORM_block4:
		/* must be location description */
		res = dwarf_attr_offset(die, attr, &offset, perr);
		llbuf = 0;
		if (res == DW_DLV_OK) {
		    Dwarf_Signed count;
		    int lres =
			dwarf_loclist(attr, &llbuf, &count, perr);
		    if (lres != DW_DLV_OK) {
			return lres;
		    }
		    if (count != 1) {
			/* this cannot happen! */
			/* perr? */
			_dwarf_error(dbg, perr,
				     DW_DLE_LOCDESC_COUNT_WRONG);
			retval = DW_DLV_ERROR;
			return retval;
		    }
		    for (i = 0; i < count; ++i) {
			unsigned int ents = llbuf[i].ld_cents;

			locp = llbuf[i].ld_s;
			for (entindx = 0; entindx < ents; entindx++) {
			    Dwarf_Loc *llocp;

			    llocp = locp + entindx;
			    if (llocp->lr_atom == DW_OP_addr) {
				send_addr_note(DW_SECTION_INFO, offset +
					       llocp->lr_offset + 1
					       /* The offset is the
					          offset of the atom,
					          ** and we know the
					          addr is 1 past it. */
					       , llocp->lr_number);
			    }
			}
		    }


		    if (count > 0) {
			for (i = 0; i < count; ++i) {
			    dwarf_dealloc(dbg, llbuf[i].ld_s,
					  DW_DLA_LOC_BLOCK);
			}
			dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC);
		    }
		} else {
		    retval = res;
		}
		break;

	    default:
		/* must be a const offset in debug_loc */
		;		/* do nothing */
	    }
	    dwarf_dealloc(dbg, attr, DW_DLA_ATTR);
	}			/* else error or no entry */
	retval = fres;
    } else {
	retval = ares;
    }
    return retval;
}
Example #4
0
error_t print_local_var(mygdb_info_t* gdb_info, Dwarf_Die var_die, char* var_name){
	Dwarf_Half tag;
	Dwarf_Error err;
	unsigned long var_addr;
	Dwarf_Attribute* attrs;
	Dwarf_Locdesc* locs_var;
	Dwarf_Signed attrcount, i, cnt_var;
	
	if (dwarf_tag(var_die, &tag, &err) != DW_DLV_OK)
		return E_FATAL;

	/* Make sure to only have a var die */
	if (tag != DW_TAG_variable)
		return E_FATAL;
		
		/* Grab the DIEs attributes */
	if (dwarf_attrlist(var_die, &attrs, &attrcount, &err) != DW_DLV_OK)
		return E_FATAL;
	
	for (i = 0; i < attrcount; ++i) {
		Dwarf_Half attrcode;
		if (dwarf_whatattr(attrs[i], &attrcode, &err) != DW_DLV_OK)
			return E_FATAL;

		
		if (attrcode == DW_AT_location)
			break;
		
	}
	
	if( attrs[i] == NULL ){
		printf("Failed to find the DW_AT_location attribute\n");
		return E_NON_FATAL;
	}
	
	if( dwarf_loclist(attrs[i], &locs_var, &cnt_var, &err) != DW_DLV_OK){
		printf("dwarf_loclist failed\n");
		return E_FATAL;
	}
	
	if((cnt_var != 1) || (locs_var[0].ld_cents != 1) || (locs_var[0].ld_s[0].lr_atom != DW_OP_fbreg)){
		fprintf(stderr, "Unexpected location information\n");
		return E_NON_FATAL;
  	}
  	
  	struct user_regs_struct regs;
  	if( ptrace(PTRACE_GETREGS, gdb_info->child_pid, NULL, &regs ) < 0 )
  		return E_FATAL;
  		
  		var_addr = (unsigned long)(regs.rbp + (long)locs_var[0].ld_s[0].lr_number + 16);
		
		errno = 0;
		unsigned long data;
		data = ptrace(PTRACE_PEEKTEXT, gdb_info->child_pid, (void*)var_addr);
		
		if(errno){
			printf("peektext failed\n");
			return E_FATAL;
		}
		
		printf("%s = %lu\n", var_name, data);
		
	return E_NONE;
}