Beispiel #1
0
/*
 * Use the DWARF expression for the Call-frame-address and determine
 * if return address is in LR and if a new frame was allocated.
 */
static int check_return_reg(int ra_regno, Dwarf_Frame *frame)
{
	Dwarf_Op ops_mem[2];
	Dwarf_Op dummy;
	Dwarf_Op *ops = &dummy;
	size_t nops;
	int result;

	result = dwarf_frame_register(frame, ra_regno, ops_mem, &ops, &nops);
	if (result < 0) {
		pr_debug("dwarf_frame_register() %s\n", dwarf_errmsg(-1));
		return -1;
	}

	/*
	 * Check if return address is on the stack. If return address
	 * is in a register (typically R0), it is yet to be saved on
	 * the stack.
	 */
	if ((nops != 0 || ops != NULL) &&
		!(nops == 1 && ops[0].atom == DW_OP_regx &&
			ops[0].number2 == 0 && ops[0].offset == 0))
		return 0;

	/*
	 * Return address is in LR. Check if a frame was allocated
	 * but not-yet used.
	 */
	result = dwarf_frame_cfa(frame, &ops, &nops);
	if (result < 0) {
		pr_debug("dwarf_frame_cfa() returns %d, %s\n", result,
					dwarf_errmsg(-1));
		return -1;
	}

	/*
	 * If call frame address is in r1, no new frame was allocated.
	 */
	if (nops == 1 && ops[0].atom == DW_OP_bregx && ops[0].number == 1 &&
				ops[0].number2 == 0)
		return 1;

	/*
	 * A new frame was allocated but has not yet been used.
	 */
	return 2;
}
Beispiel #2
0
static int
print_register (void *arg,
		int regno,
		const char *setname,
		const char *prefix,
		const char *regname,
		int bits __attribute__ ((unused)),
		int type __attribute__ ((unused)))
{
  struct stuff *stuff = arg;

  printf ("\t%s reg%u (%s%s): ", setname, regno, prefix, regname);

  Dwarf_Op ops_mem[2];
  Dwarf_Op *ops;
  size_t nops;
  int result = dwarf_frame_register (stuff->frame, regno, ops_mem, &ops, &nops);
  print_detail (result, ops, nops, stuff->bias);

  return DWARF_CB_OK;
}