Exemple #1
0
/*
   ** tuiUpdateLocatorInfoFromFrame().
   **        Function to update the locator, with the information extracted from frameInfo
 */
void
tuiUpdateLocatorInfoFromFrame (struct frame_info *frameInfo,
                               TuiLocatorElementPtr element)
{
  struct symtab_and_line symtabAndLine;

  /* now get the new info */
  symtabAndLine = find_pc_line (frameInfo->pc,
			   (frameInfo->next != (struct frame_info *) NULL &&
			    !frameInfo->next->signal_handler_caller &&
			    !frame_in_dummy (frameInfo->next)));
  if (symtabAndLine.symtab && symtabAndLine.symtab->filename)
    tuiSetLocatorInfo (symtabAndLine.symtab->filename,
		       _getFuncNameFromFrame (frameInfo),
		       symtabAndLine.line,
		       frameInfo->pc,
		       element);
  else
    tuiSetLocatorInfo ((char *) NULL,
		       _getFuncNameFromFrame (frameInfo),
		       0,
		       frameInfo->pc,
		       element);

  return;
}				/* tuiUpdateLocatorInfoFromFrame */
Exemple #2
0
CORE_ADDR
microblaze_skip_prologue (CORE_ADDR pc)
{
  CORE_ADDR func_addr, func_end;
  struct symtab_and_line sal;
  CORE_ADDR start_pc = 0;
  CORE_ADDR ostart_pc = 0;

  /* If we have line debugging information, then the end of the
     prologue should the first assembly instruction of  the first
     source line */
  /* Debugging info does not always give the right answer since 
     parameters are stored on stack after this.  Always analyze the prologue */
  if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
    {
      sal = find_pc_line (func_addr, 0);
      if (sal.end && sal.end < func_end)
	start_pc = sal.end;
    }
  ostart_pc = microblaze_analyze_prologue (NULL, pc);
  if (ostart_pc > start_pc)
    return ostart_pc;
  else
    return start_pc;
}
Exemple #3
0
static int
c_preprocess_and_parse (void)
{
  /* Set up a lookup function for the macro expander.  */
  struct macro_scope *scope = 0;
  struct cleanup *back_to = make_cleanup (free_current_contents, &scope);

  if (expression_context_block)
    scope = sal_macro_scope (find_pc_line (expression_context_pc, 0));
  else
    scope = default_macro_scope ();

  if (scope)
    {
      expression_macro_lookup_func = standard_macro_lookup;
      expression_macro_lookup_baton = (void *) scope;
    }
  else
    {
      expression_macro_lookup_func = null_macro_lookup;
      expression_macro_lookup_baton = 0;
    }

  gdb_assert (! macro_original_text);
  make_cleanup (scan_macro_cleanup, 0);

  {
    int result = c_parse ();
    do_cleanups (back_to);
    return result;
  }
}
/* Function to display the disassembly window.   */
void
tui_show_disassem_and_update_source (CORE_ADDR start_addr)
{
  struct symtab_and_line sal;

  tui_show_disassem (start_addr);
  if (tui_current_layout () == SRC_DISASSEM_COMMAND)
    {
      struct tui_line_or_address val;

      /*
         ** Update what is in the source window if it is displayed too,
         ** note that it follows what is in the disassembly window and visa-versa
       */
      sal = find_pc_line (start_addr, 0);
      val.loa = LOA_LINE;
      val.u.line_no = sal.line;
      tui_update_source_window (TUI_SRC_WIN, sal.symtab, val, TRUE);
      if (sal.symtab)
	{
	  set_current_source_symtab_and_line (&sal);
	  tui_update_locator_filename (sal.symtab->filename);
	}
      else
	tui_update_locator_filename ("?");
    }

  return;
}
Exemple #5
0
struct macro_scope *
default_macro_scope (void)
{
  struct symtab_and_line sal;
  struct macro_scope *ms;
  struct frame_info *frame;

  /* If there's a selected frame, use its PC.  */
  frame = deprecated_safe_get_selected_frame ();
  if (frame)
    sal = find_pc_line (get_frame_pc (frame), 0);
  
  /* Fall back to the current listing position.  */
  else
    {
      /* Don't call select_source_symtab here.  That can raise an
         error if symbols aren't loaded, but GDB calls the expression
         evaluator in all sorts of contexts.

         For example, commands like `set width' call the expression
         evaluator to evaluate their numeric arguments.  If the
         current language is C, then that may call this function to
         choose a scope for macro expansion.  If you don't have any
         symbol files loaded, then get_current_or_default would raise an
         error.  But `set width' shouldn't raise an error just because
         it can't decide which scope to macro-expand its argument in.  */
      struct symtab_and_line cursal = 
      			get_current_source_symtab_and_line ();
      
      sal.symtab = cursal.symtab;
      sal.line = cursal.line;
    }

  return sal_macro_scope (sal);
}
Exemple #6
0
static void
ftrace_update_lines (struct btrace_function *bfun, CORE_ADDR pc)
{
  struct symtab_and_line sal;
  const char *fullname;

  sal = find_pc_line (pc, 0);
  if (sal.symtab == NULL || sal.line == 0)
    {
      DEBUG_FTRACE ("no lines at %s", core_addr_to_string_nz (pc));
      return;
    }

  /* Check if we switched files.  This could happen if, say, a macro that
     is defined in another file is expanded here.  */
  fullname = symtab_to_fullname (sal.symtab);
  if (ftrace_skip_file (bfun, fullname))
    {
      DEBUG_FTRACE ("ignoring file at %s, file=%s",
		    core_addr_to_string_nz (pc), fullname);
      return;
    }

  /* Update the line range.  */
  bfun->lbegin = min (bfun->lbegin, sal.line);
  bfun->lend = max (bfun->lend, sal.line);

  if (record_debug > 1)
    ftrace_debug (bfun, "update lines");
}
static CORE_ADDR
d10v_skip_prologue (CORE_ADDR pc)
{
  unsigned long op;
  unsigned short op1, op2;
  CORE_ADDR func_addr, func_end;
  struct symtab_and_line sal;

  /* If we have line debugging information, then the end of the prologue
     should be the first assembly instruction of the first source line.  */
  if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
    {
      sal = find_pc_line (func_addr, 0);
      if (sal.end && sal.end < func_end)
	return sal.end;
    }

  if (target_read_memory (pc, (char *) &op, 4))
    return pc;			/* Can't access it -- assume no prologue.  */

  while (1)
    {
      op = (unsigned long) read_memory_integer (pc, 4);
      if ((op & 0xC0000000) == 0xC0000000)
	{
	  /* long instruction */
	  if (((op & 0x3FFF0000) != 0x01FF0000) &&	/* add3 sp,sp,n */
	      ((op & 0x3F0F0000) != 0x340F0000) &&	/* st  rn, @(offset,sp) */
	      ((op & 0x3F1F0000) != 0x350F0000))	/* st2w  rn, @(offset,sp) */
	    break;
	}
      else
	{
	  /* short instructions */
	  if ((op & 0xC0000000) == 0x80000000)
	    {
	      op2 = (op & 0x3FFF8000) >> 15;
	      op1 = op & 0x7FFF;
	    }
	  else
	    {
	      op1 = (op & 0x3FFF8000) >> 15;
	      op2 = op & 0x7FFF;
	    }
	  if (check_prologue (op1))
	    {
	      if (!check_prologue (op2))
		{
		  /* If the previous opcode was really part of the
		     prologue and not just a NOP, then we want to
		     break after both instructions.  */
		  if (op1 != 0x5E00)
		    pc += 4;
		  break;
		}
	    }
	  else
	    break;
	}
Exemple #8
0
static struct symtab_and_line
find_last_line_symbol (CORE_ADDR start, CORE_ADDR end, int notcurrent)
{
  struct symtab_and_line sal = find_pc_line (start, notcurrent);
  struct symtab_and_line best_sal = sal;

  if (sal.pc == 0 || sal.line == 0 || sal.end == 0)
    return sal;

  do
    {
      if (sal.line && sal.line <= best_sal.line)
	best_sal = sal;
      sal = find_pc_line (sal.end, notcurrent);
    }
  while (sal.pc && sal.pc < end);

  return best_sal;
}
static CORE_ADDR
moxie_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  CORE_ADDR func_addr = 0, func_end = 0;
  char *func_name;

  /* See if we can determine the end of the prologue via the symbol table.
     If so, then return either PC, or the PC after the prologue, whichever
     is greater.  */
  if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end))
    {
      CORE_ADDR post_prologue_pc
	= skip_prologue_using_sal (gdbarch, func_addr);
      if (post_prologue_pc != 0)
	return max (pc, post_prologue_pc);
      else
	{
	  /* Can't determine prologue from the symbol table, need to examine
	     instructions.  */
	  struct symtab_and_line sal;
	  struct symbol *sym;
	  struct moxie_frame_cache cache;
	  CORE_ADDR plg_end;
	  
	  memset (&cache, 0, sizeof cache);
	  
	  plg_end = moxie_analyze_prologue (func_addr, 
					    func_end, &cache, NULL);
	  /* Found a function.  */
	  sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL);
	  /* Don't use line number debug info for assembly source
	     files. */
	  if (sym && SYMBOL_LANGUAGE (sym) != language_asm)
	    {
	      sal = find_pc_line (func_addr, 0);
	      if (sal.end && sal.end < func_end)
		{
		  /* Found a line number, use it as end of
		     prologue.  */
		  return sal.end;
		}
	    }
	  /* No useable line symbol.  Use result of prologue parsing
	     method.  */
	  return plg_end;
	}
    }

  /* No function symbol -- just return the PC.  */
  return (CORE_ADDR) pc;
}
static CORE_ADDR
sparc32_skip_prologue (CORE_ADDR start_pc)
{
  struct symtab_and_line sal;
  CORE_ADDR func_start, func_end;
  struct sparc_frame_cache cache;

  /* This is the preferred method, find the end of the prologue by
     using the debugging information.  */
  if (find_pc_partial_function (start_pc, NULL, &func_start, &func_end))
    {
      sal = find_pc_line (func_start, 0);

      if (sal.end < func_end
	  && start_pc <= sal.end)
	return sal.end;
    }

  start_pc = sparc_analyze_prologue (start_pc, 0xffffffffUL, &cache);

  /* The psABI says that "Although the first 6 words of arguments
     reside in registers, the standard stack frame reserves space for
     them.".  It also suggests that a function may use that space to
     "write incoming arguments 0 to 5" into that space, and that's
     indeed what GCC seems to be doing.  In that case GCC will
     generate debug information that points to the stack slots instead
     of the registers, so we should consider the instructions that
     write out these incoming arguments onto the stack.  Of course we
     only need to do this if we have a stack frame.  */

  while (!cache.frameless_p)
    {
      unsigned long insn = sparc_fetch_instruction (start_pc);

      /* Recognize instructions that store incoming arguments in
         %i0...%i5 into the corresponding stack slot.  */
      if (X_OP (insn) == 3 && (X_OP3 (insn) & 0x3c) == 0x04 && X_I (insn)
	  && (X_RD (insn) >= 24 && X_RD (insn) <= 29) && X_RS1 (insn) == 30
	  && X_SIMM13 (insn) == 68 + (X_RD (insn) - 24) * 4)
	{
	  start_pc += 4;
	  continue;
	}

      break;
    }

  return start_pc;
}
Exemple #11
0
void
symify(const char *s, char **function, char **file, int *line, int _diff)
{
  struct minimal_symbol *msymbol = NULL;
  struct symtab_and_line sal;
  struct symtabs_and_lines sals;
  struct symtab *symtab;
  struct symbol *symbol;
  unsigned long core;
  long diff;
  char *tmp = alloca(100);
  int sl;
  char diff_string[100];

  *function = NULL;
  *file = NULL;
  sscanf(s, "%lx", &core);
  core += _diff;
  sprintf(tmp, "*%ld", core);
  sals = decode_line_spec(tmp, 0);
  if (!sals.sals[0].symtab)
  {
    msymbol = lookup_minimal_symbol_by_pc(core);
    if (!msymbol)
    {
      *line = 0;
      return;
    }
    diff = core - SYMBOL_VALUE_ADDRESS(msymbol);
    sl = strlen(SYMBOL_NAME(msymbol));
    sprintf(diff_string, "%+ld", diff);
    sl += strlen(diff_string);
    *function = (char *) malloc(sl + 1);
    strcpy(*function, SYMBOL_NAME(msymbol));
    strcat(*function, diff_string);
    *line = 0;
    return;
  }
  sal = find_pc_line(core, 1);
  symbol = find_pc_function(core);
  symtab = sal.symtab;
  sl = strlen(SYMBOL_SOURCE_NAME(symbol));
  *function = (char *) malloc(sl + 1);
  strcpy(*function, SYMBOL_SOURCE_NAME(symbol));
  sl = strlen(symtab->filename);
  *file = (char *) malloc(sl + 1);
  strcpy(*file, symtab->filename);
  *line = sal.line;
}
Exemple #12
0
struct macro_scope *
default_macro_scope (void)
{
  struct symtab_and_line sal;
  struct macro_source_file *main;
  struct macro_scope *ms;

  /* If there's a selected frame, use its PC.  */ 
  if (selected_frame)
    sal = find_pc_line (selected_frame->pc, 0);
  
  /* If the target has any registers at all, then use its PC.  Why we
     would have registers but no stack, I'm not sure.  */
  else if (target_has_registers)
    sal = find_pc_line (read_pc (), 0);

  /* If all else fails, fall back to the current listing position.  */
  else
    {
      /* Don't call select_source_symtab here.  That can raise an
         error if symbols aren't loaded, but GDB calls the expression
         evaluator in all sorts of contexts.

         For example, commands like `set width' call the expression
         evaluator to evaluate their numeric arguments.  If the
         current language is C, then that may call this function to
         choose a scope for macro expansion.  If you don't have any
         symbol files loaded, then select_source_symtab will raise an
         error.  But `set width' shouldn't raise an error just because
         it can't decide which scope to macro-expand its argument in.  */
      sal.symtab = current_source_symtab;
      sal.line = current_source_line;
    }

  return sal_macro_scope (sal);
}
static void
write_macro_definitions (const struct block *block, CORE_ADDR pc,
			 struct ui_file *file)
{
  struct macro_scope *scope;

  if (block != NULL)
    scope = sal_macro_scope (find_pc_line (pc, 0));
  else
    scope = default_macro_scope ();
  if (scope == NULL)
    scope = user_macro_scope ();

  if (scope != NULL && scope->file != NULL && scope->file->table != NULL)
    macro_for_each_in_scope (scope->file, scope->line, print_one_macro, file);
}
PyObject *
recpy_bt_insn_sal (PyObject *self, void *closure)
{
  const btrace_insn * const insn = btrace_insn_from_recpy_insn (self);
  PyObject *result = NULL;

  if (insn == NULL)
    return NULL;

  TRY
    {
      result = symtab_and_line_to_sal_object (find_pc_line (insn->pc, 0));
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      GDB_PY_HANDLE_EXCEPTION (except);
    }
Exemple #15
0
static SCM
gdbscm_find_pc_line (SCM pc_scm)
{
  ULONGEST pc_ull;
  struct symtab_and_line sal;
  volatile struct gdb_exception except;

  init_sal (&sal); /* -Wall */

  gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, NULL, "U", pc_scm, &pc_ull);

  TRY_CATCH (except, RETURN_MASK_ALL)
    {
      CORE_ADDR pc = (CORE_ADDR) pc_ull;

      sal = find_pc_line (pc, 0);
    }
static CORE_ADDR
m88k_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  struct symtab_and_line sal;
  CORE_ADDR func_start, func_end;

  /* This is the preferred method, find the end of the prologue by
     using the debugging information.  */
  if (find_pc_partial_function (pc, NULL, &func_start, &func_end))
    {
      sal = find_pc_line (func_start, 0);

      if (sal.end < func_end && pc <= sal.end)
	return sal.end;
    }

  return m88k_analyze_prologue (pc, pc + m88k_max_prologue_size, NULL);
}
Exemple #17
0
static CORE_ADDR
sparc32_skip_prologue (CORE_ADDR start_pc)
{
  struct symtab_and_line sal;
  CORE_ADDR func_start, func_end;
  struct sparc_frame_cache cache;

  /* This is the preferred method, find the end of the prologue by
     using the debugging information.  */
  if (find_pc_partial_function (start_pc, NULL, &func_start, &func_end))
    {
      sal = find_pc_line (func_start, 0);

      if (sal.end < func_end
	  && start_pc <= sal.end)
	return sal.end;
    }

  return sparc_analyze_prologue (start_pc, 0xffffffffUL, &cache);
}
Exemple #18
0
static SCM
gdbscm_find_pc_line (SCM pc_scm)
{
  ULONGEST pc_ull;
  struct symtab_and_line sal;

  init_sal (&sal); /* -Wall */

  gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, NULL, "U", pc_scm, &pc_ull);

  TRY
    {
      CORE_ADDR pc = (CORE_ADDR) pc_ull;

      sal = find_pc_line (pc, 0);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      GDBSCM_HANDLE_GDB_EXCEPTION (except);
    }
/* Function to display the "main" routine.  */
void
tui_display_main (void)
{
  if ((tui_source_windows ())->count > 0)
    {
      CORE_ADDR addr;

      addr = tui_get_begin_asm_address ();
      if (addr != (CORE_ADDR) 0)
	{
	  struct symtab_and_line sal;

	  tui_update_source_windows_with_addr (addr);
	  sal = find_pc_line (addr, 0);
          if (sal.symtab)
             tui_update_locator_filename (sal.symtab->filename);
          else
             tui_update_locator_filename ("??");
	}
    }
}
/* Function to display the "main" routine.  */
void
tui_display_main (void)
{
  if ((tui_source_windows ())->count > 0)
    {
      struct gdbarch *gdbarch;
      CORE_ADDR addr;

      tui_get_begin_asm_address (&gdbarch, &addr);
      if (addr != (CORE_ADDR) 0)
	{
	  struct symtab_and_line sal;

	  tui_update_source_windows_with_addr (gdbarch, addr);
	  sal = find_pc_line (addr, 0);
          if (sal.symtab)
             tui_update_locator_fullname (symtab_to_fullname (sal.symtab));
          else
             tui_update_locator_fullname ("??");
	}
    }
}
Exemple #21
0
static void
save_bookmark_command (char *args, int from_tty)
{
  /* Get target's idea of a bookmark.  */
  gdb_byte *bookmark_id = target_get_bookmark (args, from_tty);
  struct bookmark *b, *b1;
  struct gdbarch *gdbarch = get_regcache_arch (get_current_regcache ());

  /* CR should not cause another identical bookmark.  */
  dont_repeat ();

  if (bookmark_id == NULL)
    error (_("target_get_bookmark failed."));

  /* Set up a bookmark struct.  */
  b = xcalloc (1, sizeof (struct bookmark));
  b->number = ++bookmark_count;
  init_sal (&b->sal);
  b->pc = regcache_read_pc (get_current_regcache ());
  b->sal = find_pc_line (b->pc, 0);
  b->sal.pspace = get_frame_program_space (get_current_frame ());
  b->opaque_data = bookmark_id;
  b->next = NULL;

  /* Add this bookmark to the end of the chain, so that a list
     of bookmarks will come out in order of increasing numbers.  */

  b1 = bookmark_chain;
  if (b1 == 0)
    bookmark_chain = b;
  else
    {
      while (b1->next)
	b1 = b1->next;
      b1->next = b;
    }
  printf_filtered (_("Saved bookmark %d at %s\n"), b->number,
		     paddress (gdbarch, b->sal.pc));
}
Exemple #22
0
/* Function to ensure that the source and/or disassemly windows
   reflect the input address.  */
void
tui_update_source_windows_with_addr (struct gdbarch *gdbarch, CORE_ADDR addr)
{
  if (addr != 0)
    {
      struct symtab_and_line sal;
      struct tui_line_or_address l;
      
      switch (tui_current_layout ())
	{
	case DISASSEM_COMMAND:
	case DISASSEM_DATA_COMMAND:
	  tui_show_disassem (gdbarch, addr);
	  break;
	case SRC_DISASSEM_COMMAND:
	  tui_show_disassem_and_update_source (gdbarch, addr);
	  break;
	default:
	  sal = find_pc_line (addr, 0);
	  l.loa = LOA_LINE;
	  l.u.line_no = sal.line;
	  tui_show_symtab_source (gdbarch, sal.symtab, l, FALSE);
	  break;
	}
    }
  else
    {
      int i;

      for (i = 0; i < (tui_source_windows ())->count; i++)
	{
	  struct tui_win_info *win_info = (tui_source_windows ())->list[i];

	  tui_clear_source_content (win_info, EMPTY_SOURCE_PROMPT);
	  tui_clear_exec_info_content (win_info);
	}
    }
}
Exemple #23
0
/* The idea here is to present a source-O-centric view of a
   function to the user.  This means that things are presented
   in source order, with (possibly) out of order assembly
   immediately following.  */
static void
do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
			      struct disassemble_info *di, int nlines,
			      struct linetable_entry *le,
			      CORE_ADDR low, CORE_ADDR high,
			      struct symtab *symtab,
			      int how_many, int flags, struct ui_stream *stb)
{
  int newlines = 0;
  struct dis_line_entry *mle;
  struct symtab_and_line sal;
  int i;
  int out_of_order = 0;
  int next_line = 0;
  CORE_ADDR pc;
  int num_displayed = 0;
  struct cleanup *ui_out_chain;
  struct cleanup *ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
  struct cleanup *ui_out_list_chain = make_cleanup (null_cleanup, 0);

  mle = (struct dis_line_entry *) alloca (nlines
					  * sizeof (struct dis_line_entry));

  /* Copy linetable entries for this function into our data
     structure, creating end_pc's and setting out_of_order as
     appropriate.  */

  /* First, skip all the preceding functions.  */

  for (i = 0; i < nlines - 1 && le[i].pc < low; i++);

  /* Now, copy all entries before the end of this function.  */

  for (; i < nlines - 1 && le[i].pc < high; i++)
    {
      if (le[i].line == le[i + 1].line && le[i].pc == le[i + 1].pc)
	continue;		/* Ignore duplicates */

      /* Skip any end-of-function markers.  */
      if (le[i].line == 0)
	continue;

      mle[newlines].line = le[i].line;
      if (le[i].line > le[i + 1].line)
	out_of_order = 1;
      mle[newlines].start_pc = le[i].pc;
      mle[newlines].end_pc = le[i + 1].pc;
      newlines++;
    }

  /* If we're on the last line, and it's part of the function,
     then we need to get the end pc in a special way.  */

  if (i == nlines - 1 && le[i].pc < high)
    {
      mle[newlines].line = le[i].line;
      mle[newlines].start_pc = le[i].pc;
      sal = find_pc_line (le[i].pc, 0);
      mle[newlines].end_pc = sal.end;
      newlines++;
    }

  /* Now, sort mle by line #s (and, then by addresses within
     lines). */

  if (out_of_order)
    qsort (mle, newlines, sizeof (struct dis_line_entry), compare_lines);

  /* Now, for each line entry, emit the specified lines (unless
     they have been emitted before), followed by the assembly code
     for that line.  */

  ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");

  for (i = 0; i < newlines; i++)
    {
      /* Print out everything from next_line to the current line.  */
      if (mle[i].line >= next_line)
	{
	  if (next_line != 0)
	    {
	      /* Just one line to print. */
	      if (next_line == mle[i].line)
		{
		  ui_out_tuple_chain
		    = make_cleanup_ui_out_tuple_begin_end (uiout,
							   "src_and_asm_line");
		  print_source_lines (symtab, next_line, mle[i].line + 1, 0);
		}
	      else
		{
		  /* Several source lines w/o asm instructions associated. */
		  for (; next_line < mle[i].line; next_line++)
		    {
		      struct cleanup *ui_out_list_chain_line;
		      struct cleanup *ui_out_tuple_chain_line;
		      
		      ui_out_tuple_chain_line
			= make_cleanup_ui_out_tuple_begin_end (uiout,
							       "src_and_asm_line");
		      print_source_lines (symtab, next_line, next_line + 1,
					  0);
		      ui_out_list_chain_line
			= make_cleanup_ui_out_list_begin_end (uiout,
							      "line_asm_insn");
		      do_cleanups (ui_out_list_chain_line);
		      do_cleanups (ui_out_tuple_chain_line);
		    }
		  /* Print the last line and leave list open for
		     asm instructions to be added. */
		  ui_out_tuple_chain
		    = make_cleanup_ui_out_tuple_begin_end (uiout,
							   "src_and_asm_line");
		  print_source_lines (symtab, next_line, mle[i].line + 1, 0);
		}
	    }
	  else
	    {
	      ui_out_tuple_chain
		= make_cleanup_ui_out_tuple_begin_end (uiout, "src_and_asm_line");
	      print_source_lines (symtab, mle[i].line, mle[i].line + 1, 0);
	    }

	  next_line = mle[i].line + 1;
	  ui_out_list_chain
	    = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn");
	}

      num_displayed += dump_insns (gdbarch, uiout, di,
				   mle[i].start_pc, mle[i].end_pc,
				   how_many, flags, stb);

      /* When we've reached the end of the mle array, or we've seen the last
         assembly range for this source line, close out the list/tuple.  */
      if (i == (newlines - 1) || mle[i + 1].line > mle[i].line)
	{
	  do_cleanups (ui_out_list_chain);
	  do_cleanups (ui_out_tuple_chain);
	  ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
	  ui_out_list_chain = make_cleanup (null_cleanup, 0);
	  ui_out_text (uiout, "\n");
	}
      if (how_many >= 0 && num_displayed >= how_many)
	break;
    }
  do_cleanups (ui_out_chain);
}
Exemple #24
0
static int
arm_linux_copy_svc (struct gdbarch *gdbarch, uint32_t insn, CORE_ADDR to,
		    struct regcache *regs, struct displaced_step_closure *dsc)
{
  CORE_ADDR from = dsc->insn_addr;
  struct frame_info *frame;
  unsigned int svc_number = displaced_read_reg (regs, from, 7);

  if (debug_displaced)
    fprintf_unfiltered (gdb_stdlog, "displaced: copying Linux svc insn %.8lx\n",
			(unsigned long) insn);

  frame = get_current_frame ();

  /* Is this a sigreturn or rt_sigreturn syscall?  Note: these are only useful
     for EABI.  */
  if (svc_number == 119 || svc_number == 173)
    {
      if (get_frame_type (frame) == SIGTRAMP_FRAME)
	{
	  CORE_ADDR return_to;
	  struct symtab_and_line sal;

	  if (debug_displaced)
	    fprintf_unfiltered (gdb_stdlog, "displaced: found "
	      "sigreturn/rt_sigreturn SVC call. PC in frame = %lx\n",
	      (unsigned long) get_frame_pc (frame));

	  return_to = frame_unwind_caller_pc (frame);
	  if (debug_displaced)
	    fprintf_unfiltered (gdb_stdlog, "displaced: unwind pc = %lx. "
	      "Setting momentary breakpoint.\n", (unsigned long) return_to);

	  gdb_assert (inferior_thread ()->step_resume_breakpoint == NULL);

	  sal = find_pc_line (return_to, 0);
	  sal.pc = return_to;
	  sal.section = find_pc_overlay (return_to);
	  sal.explicit_pc = 1;

	  frame = get_prev_frame (frame);

	  if (frame)
	    {
	      inferior_thread ()->step_resume_breakpoint
        	= set_momentary_breakpoint (gdbarch, sal, get_frame_id (frame),
					    bp_step_resume);

	      /* We need to make sure we actually insert the momentary
	         breakpoint set above.  */
	      insert_breakpoints ();
	    }
	  else if (debug_displaced)
	    fprintf_unfiltered (gdb_stderr, "displaced: couldn't find previous "
				"frame to set momentary breakpoint for "
				"sigreturn/rt_sigreturn\n");
	}
      else if (debug_displaced)
	fprintf_unfiltered (gdb_stdlog, "displaced: sigreturn/rt_sigreturn "
			    "SVC call not in signal trampoline frame\n");
    }

  /* Preparation: If we detect sigreturn, set momentary breakpoint at resume
		  location, else nothing.
     Insn: unmodified svc.
     Cleanup: if pc lands in scratch space, pc <- insn_addr + 4
              else leave pc alone.  */

  dsc->modinsn[0] = insn;

  dsc->cleanup = &arm_linux_cleanup_svc;
  /* Pretend we wrote to the PC, so cleanup doesn't set PC to the next
     instruction.  */
  dsc->wrote_to_pc = 1;

  return 0;
}
Exemple #25
0
static int
arm_linux_copy_svc (struct gdbarch *gdbarch, struct regcache *regs,
		    struct displaced_step_closure *dsc)
{
  CORE_ADDR return_to = 0;

  struct frame_info *frame;
  unsigned int svc_number = displaced_read_reg (regs, dsc, 7);
  int is_sigreturn = 0;
  int is_thumb;

  frame = get_current_frame ();

  is_sigreturn = arm_linux_sigreturn_return_addr(frame, svc_number,
						 &return_to, &is_thumb);
  if (is_sigreturn)
    {
	  struct symtab_and_line sal;

	  if (debug_displaced)
	    fprintf_unfiltered (gdb_stdlog, "displaced: found "
	      "sigreturn/rt_sigreturn SVC call.  PC in frame = %lx\n",
	      (unsigned long) get_frame_pc (frame));

	  if (debug_displaced)
	    fprintf_unfiltered (gdb_stdlog, "displaced: unwind pc = %lx.  "
	      "Setting momentary breakpoint.\n", (unsigned long) return_to);

	  gdb_assert (inferior_thread ()->control.step_resume_breakpoint
		      == NULL);

	  sal = find_pc_line (return_to, 0);
	  sal.pc = return_to;
	  sal.section = find_pc_overlay (return_to);
	  sal.explicit_pc = 1;

	  frame = get_prev_frame (frame);

	  if (frame)
	    {
	      inferior_thread ()->control.step_resume_breakpoint
        	= set_momentary_breakpoint (gdbarch, sal, get_frame_id (frame),
					    bp_step_resume);

	      /* set_momentary_breakpoint invalidates FRAME.  */
	      frame = NULL;

	      /* We need to make sure we actually insert the momentary
	         breakpoint set above.  */
	      insert_breakpoints ();
	    }
	  else if (debug_displaced)
	    fprintf_unfiltered (gdb_stderr, "displaced: couldn't find previous "
				"frame to set momentary breakpoint for "
				"sigreturn/rt_sigreturn\n");
	}
      else if (debug_displaced)
	fprintf_unfiltered (gdb_stdlog, "displaced: sigreturn/rt_sigreturn "
			    "SVC call not in signal trampoline frame\n");
    

  /* Preparation: If we detect sigreturn, set momentary breakpoint at resume
		  location, else nothing.
     Insn: unmodified svc.
     Cleanup: if pc lands in scratch space, pc <- insn_addr + 4
              else leave pc alone.  */


  dsc->cleanup = &arm_linux_cleanup_svc;
  /* Pretend we wrote to the PC, so cleanup doesn't set PC to the next
     instruction.  */
  dsc->wrote_to_pc = 1;

  return 0;
}