Ejemplo n.º 1
0
char *
find_separate_debug_file_by_buildid (struct objfile *objfile)
{
  const struct bfd_build_id *build_id;

  build_id = build_id_bfd_get (objfile->obfd);
  if (build_id != NULL)
    {
      if (separate_debug_file_debug)
	printf_unfiltered (_("\nLooking for separate debug info (build-id) for "
			     "%s\n"), objfile_name (objfile));

      gdb_bfd_ref_ptr abfd (build_id_to_debug_bfd (build_id->size,
						   build_id->data));
      /* Prevent looping on a stripped .debug file.  */
      if (abfd != NULL
	  && filename_cmp (bfd_get_filename (abfd.get ()),
			   objfile_name (objfile)) == 0)
	warning (_("\"%s\": separate debug info file has no debug info"),
		 bfd_get_filename (abfd.get ()));
      else if (abfd != NULL)
	return xstrdup (bfd_get_filename (abfd.get ()));
    }
  return NULL;
}
Ejemplo n.º 2
0
struct macro_source_file *
macro_lookup_inclusion (struct macro_source_file *source, const char *name)
{
  /* Is SOURCE itself named NAME?  */
  if (filename_cmp (name, source->filename) == 0)
    return source;

  /* It's not us.  Try all our children, and return the lowest.  */
  {
    struct macro_source_file *child;
    struct macro_source_file *best = NULL;
    int best_depth = 0;

    for (child = source->includes; child; child = child->next_included)
      {
        struct macro_source_file *result
          = macro_lookup_inclusion (child, name);

        if (result)
          {
            int result_depth = inclusion_depth (result);

            if (! best || result_depth < best_depth)
              {
                best = result;
                best_depth = result_depth;
              }
          }
      }

    return best;
  }
}
Ejemplo n.º 3
0
static int
cmp_bb (const PTR lp, const PTR rp)
{
  int r;
  const Sym *left = *(const Sym **) lp;
  const Sym *right = *(const Sym **) rp;

  if (left->file && right->file)
    {
      r = filename_cmp (left->file->name, right->file->name);

      if (r)
	return r;

      if (left->line_num != right->line_num)
	return left->line_num - right->line_num;
    }

  if (left->addr < right->addr)
    return -1;
  else if (left->addr > right->addr)
    return 1;
  else
    return 0;
}
Ejemplo n.º 4
0
char *
find_separate_debug_file_by_buildid (struct objfile *objfile)
{
  const struct elf_build_id *build_id;

  build_id = build_id_bfd_get (objfile->obfd);
  if (build_id != NULL)
    {
      bfd *abfd;

      abfd = build_id_to_debug_bfd (build_id->size, build_id->data);
      /* Prevent looping on a stripped .debug file.  */
      if (abfd != NULL
	  && filename_cmp (bfd_get_filename (abfd),
			   objfile_name (objfile)) == 0)
        {
	  warning (_("\"%s\": separate debug info file has no debug info"),
		   bfd_get_filename (abfd));
	  gdb_bfd_unref (abfd);
	}
      else if (abfd != NULL)
	{
	  char *result = xstrdup (bfd_get_filename (abfd));

	  gdb_bfd_unref (abfd);
	  return result;
	}
    }
  return NULL;
}
Ejemplo n.º 5
0
Archivo: corefile.c Proyecto: 5kg/gdb
bfd_boolean
generic_core_file_matches_executable_p (bfd *core_bfd, bfd *exec_bfd)
{
  char *exec;
  char *core;
  char *last_slash;

  if (exec_bfd == NULL || core_bfd == NULL)
    return TRUE;

  /* The cast below is to avoid a compiler warning due to the assignment
     of the const char * returned by bfd_core_file_failing_command to a
     non-const char *.  In this case, the assignement does not lead to
     breaking the const, as we're only reading the string.  */

  core = (char *) bfd_core_file_failing_command (core_bfd);
  if (core == NULL)
    return TRUE;

  exec = bfd_get_filename (exec_bfd);
  if (exec == NULL)
    return TRUE;

  last_slash = strrchr (core, '/');
  if (last_slash != NULL)
    core = last_slash + 1;

  last_slash = strrchr (exec, '/');
  if (last_slash != NULL)
    exec = last_slash + 1;

  return filename_cmp (exec, core) == 0;
}
Ejemplo n.º 6
0
int
tui_update_breakpoint_info (struct tui_win_info *win, 
			    int current_only)
{
  int i;
  int need_refresh = 0;
  struct tui_source_info *src = &win->detail.source_info;

  for (i = 0; i < win->generic.content_size; i++)
    {
      struct breakpoint *bp;
      extern struct breakpoint *breakpoint_chain;
      int mode;
      struct tui_source_element *line;

      line = &((struct tui_win_element *)
	       win->generic.content[i])->which_element.source;
      if (current_only && !line->is_exec_point)
         continue;

      /* Scan each breakpoint to see if the current line has something to
         do with it.  Identify enable/disabled breakpoints as well as
         those that we already hit.  */
      mode = 0;
      for (bp = breakpoint_chain;
           bp != (struct breakpoint *) NULL;
           bp = bp->next)
        {
	  gdb_assert (line->line_or_addr.loa == LOA_LINE
		      || line->line_or_addr.loa == LOA_ADDRESS);
          if ((win == TUI_SRC_WIN
               && bp->source_file
               && (filename_cmp (src->filename, bp->source_file) == 0)
	       && line->line_or_addr.loa == LOA_LINE
               && bp->line_number == line->line_or_addr.u.line_no)
              || (win == TUI_DISASM_WIN
		  && line->line_or_addr.loa == LOA_ADDRESS
		  && bp->loc != NULL
                  && bp->loc->address == line->line_or_addr.u.addr))
            {
              if (bp->enable_state == bp_disabled)
                mode |= TUI_BP_DISABLED;
              else
                mode |= TUI_BP_ENABLED;
              if (bp->hit_count)
                mode |= TUI_BP_HIT;
              if (bp->loc->cond)
                mode |= TUI_BP_CONDITIONAL;
              if (bp->type == bp_hardware_breakpoint)
                mode |= TUI_BP_HARDWARE;
            }
        }
      if (line->has_break != mode)
        {
          line->has_break = mode;
          need_refresh = 1;
        }
    }
  return need_refresh;
}
Ejemplo n.º 7
0
void
ldfile_open_file (lang_input_statement_type *entry)
{
  if (entry->the_bfd != NULL)
    return;

  if (! entry->flags.search_dirs)
    {
      if (ldfile_try_open_bfd (entry->filename, entry))
	return;

      if (filename_cmp (entry->filename, entry->local_sym_name) != 0)
	einfo (_("%P: cannot find %s (%s): %E\n"),
	       entry->filename, entry->local_sym_name);
      else
	einfo (_("%P: cannot find %s: %E\n"), entry->local_sym_name);

      entry->flags.missing_file = TRUE;
      input_flags.missing_file = TRUE;
    }
  else
    {
      search_arch_type *arch;
      bfd_boolean found = FALSE;

      /* Try to open <filename><suffix> or lib<filename><suffix>.a */
      for (arch = search_arch_head; arch != NULL; arch = arch->next)
	{
	  found = ldfile_open_file_search (arch->name, entry, "lib", ".a");
	  if (found)
	    break;
#ifdef VMS
	  found = ldfile_open_file_search (arch->name, entry, ":lib", ".a");
	  if (found)
	    break;
#endif
	  found = ldemul_find_potential_libraries (arch->name, entry);
	  if (found)
	    break;
	}

      /* If we have found the file, we don't need to search directories
	 again.  */
      if (found)
	entry->flags.search_dirs = FALSE;
      else
	{
	  if (entry->flags.sysrooted
	       && ld_sysroot
	       && IS_ABSOLUTE_PATH (entry->local_sym_name))
	    einfo (_("%P: cannot find %s inside %s\n"),
		   entry->local_sym_name, ld_sysroot);
	  else
	    einfo (_("%P: cannot find %s\n"), entry->local_sym_name);
	  entry->flags.missing_file = TRUE;
	  input_flags.missing_file = TRUE;
	}
    }
}
Ejemplo n.º 8
0
/* Answer whether the source is currently displayed in the source
   window.  */
int
tui_source_is_displayed (const char *fname)
{
  return (TUI_SRC_WIN != NULL
	  && TUI_SRC_WIN->generic.content_in_use 
	  && (filename_cmp (((struct tui_win_element *)
			     (tui_locator_win_info_ptr ())->
			     content[0])->which_element.locator.file_name,
			    fname) == 0));
}
Ejemplo n.º 9
0
static int
ftrace_skip_file (const struct btrace_function *bfun, const char *fullname)
{
  struct symbol *sym;
  const char *bfile;

  sym = bfun->sym;
  if (sym == NULL)
    return 1;

  bfile = symtab_to_fullname (symbol_symtab (sym));

  return (filename_cmp (bfile, fullname) != 0);
}
Ejemplo n.º 10
0
static int
check_breakpoint_by_pos(VALUE breakpoint_object, char *file, int line)
{
    breakpoint_t *breakpoint;

    if(breakpoint_object == Qnil)
        return 0;
    Data_Get_Struct(breakpoint_object, breakpoint_t, breakpoint);
    if (Qtrue != breakpoint->enabled) return 0;
    if(breakpoint->line != line)
        return 0;
    if(filename_cmp(breakpoint->source, file))
        return 1;
    return 0;
}
Ejemplo n.º 11
0
void gui_Qsort(char *v[], int left, int right)
{
	int i, last;

	if (left >= right) return;

	gui_swap(v, left, (left + right)/2);
	last = left;
	for (i=left+1; i<=right; i++)
		if (filename_cmp(v[i], v[left]) < 0)
			gui_swap(v, ++last, i);
	gui_swap(v, left, last);
	gui_Qsort(v, left, last-1);
	gui_Qsort(v, last+1, right);
}
Ejemplo n.º 12
0
/* Initializes the syscalls_info structure according to the
   architecture.  */
static void
init_syscalls_info (struct gdbarch *gdbarch)
{
  struct syscalls_info *syscalls_info = gdbarch_syscalls_info (gdbarch);
  const char *xml_syscall_file = gdbarch_xml_syscall_file (gdbarch);

  /* Should we re-read the XML info for this target?  */
  if (syscalls_info != NULL && !syscalls_info->my_gdb_datadir.empty ()
      && filename_cmp (syscalls_info->my_gdb_datadir.c_str (),
		       gdb_datadir) != 0)
    {
      /* The data-directory changed from the last time we used it.
	 It means that we have to re-read the XML info.  */
      delete syscalls_info;
      syscalls_info = NULL;
      set_gdbarch_syscalls_info (gdbarch, NULL);
    }

  /* Did we succeed at initializing this?  */
  if (syscalls_info != NULL)
    return;

  syscalls_info = xml_init_syscalls_info (xml_syscall_file);

  /* If there was some error reading the XML file, we initialize
     gdbarch->syscalls_info anyway, in order to store information
     about our attempt.  */
  if (syscalls_info == NULL)
    syscalls_info = new struct syscalls_info ();

  if (syscalls_info->syscalls.empty ())
    {
      if (xml_syscall_file != NULL)
	warning (_("Could not load the syscall XML file `%s/%s'."),
		 gdb_datadir, xml_syscall_file);
      else
	warning (_("There is no XML file to open."));

      warning (_("GDB will not be able to display "
		 "syscall names nor to verify if\n"
		 "any provided syscall numbers are valid."));
    }

  /* Saving the data-directory used to read this XML info.  */
  syscalls_info->my_gdb_datadir.assign (gdb_datadir);

  set_gdbarch_syscalls_info (gdbarch, syscalls_info);
}
Ejemplo n.º 13
0
static int
check_breakpoint_by_pos(VALUE rb_breakpoint, char *file, int line)
{
  breakpoint_t *breakpoint;

  if (NIL_P(rb_breakpoint))
    return 0;

  Data_Get_Struct(rb_breakpoint, breakpoint_t, breakpoint);

  if (Qfalse == breakpoint->enabled || breakpoint->type != BP_POS_TYPE
      || breakpoint->pos.line != line)
    return 0;

  return filename_cmp(breakpoint->source, file);
}
Ejemplo n.º 14
0
static int
check_breakpoint_by_pos(VALUE breakpoint, const char *file, int line)
{
    debug_breakpoint_t *debug_breakpoint;

    if(breakpoint == Qnil)
        return 0;
    Data_Get_Struct(breakpoint, debug_breakpoint_t, debug_breakpoint);
    if (!Qtrue == debug_breakpoint->enabled) return 0;
    if(debug_breakpoint->type != BP_POS_TYPE)
        return 0;
    if(debug_breakpoint->pos.line != line)
        return 0;
    if(filename_cmp(debug_breakpoint->source, file))
        return 1;
    return 0;
}
Ejemplo n.º 15
0
void
register_dependency (const char *filename)
{
  struct dependency *dep;

  if (dep_file == NULL)
    return;

  for (dep = dep_chain; dep != NULL; dep = dep->next)
    {
      if (!filename_cmp (filename, dep->file))
	return;
    }

  dep = XNEW (struct dependency);
  dep->file = strdup (filename);
  dep->next = dep_chain;
  dep_chain = dep;
}
Ejemplo n.º 16
0
void
register_dependency (char *filename)
{
  struct dependency *dep;

  if (dep_file == NULL)
    return;

  for (dep = dep_chain; dep != NULL; dep = dep->next)
    {
      if (!filename_cmp (filename, dep->file))
	return;
    }

  dep = (struct dependency *) xmalloc (sizeof (struct dependency));
  dep->file = xstrdup (filename);
  dep->next = dep_chain;
  dep_chain = dep;
}
Ejemplo n.º 17
0
static int
ftrace_function_switched (const struct btrace_function *bfun,
			  const struct minimal_symbol *mfun,
			  const struct symbol *fun)
{
  struct minimal_symbol *msym;
  struct symbol *sym;

  msym = bfun->msym;
  sym = bfun->sym;

  /* If the minimal symbol changed, we certainly switched functions.  */
  if (mfun != NULL && msym != NULL
      && strcmp (MSYMBOL_LINKAGE_NAME (mfun), MSYMBOL_LINKAGE_NAME (msym)) != 0)
    return 1;

  /* If the symbol changed, we certainly switched functions.  */
  if (fun != NULL && sym != NULL)
    {
      const char *bfname, *fname;

      /* Check the function name.  */
      if (strcmp (SYMBOL_LINKAGE_NAME (fun), SYMBOL_LINKAGE_NAME (sym)) != 0)
	return 1;

      /* Check the location of those functions, as well.  */
      bfname = symtab_to_fullname (symbol_symtab (sym));
      fname = symtab_to_fullname (symbol_symtab (fun));
      if (filename_cmp (fname, bfname) != 0)
	return 1;
    }

  /* If we lost symbol information, we switched functions.  */
  if (!(msym == NULL && sym == NULL) && mfun == NULL && fun == NULL)
    return 1;

  /* If we gained symbol information, we switched functions.  */
  if (msym == NULL && sym == NULL && !(mfun == NULL && fun == NULL))
    return 1;

  return 0;
}
Ejemplo n.º 18
0
bool
found_minimal_symbols::maybe_collect (const char *sfile,
				      struct objfile *objfile,
				      minimal_symbol *msymbol)
{
  switch (MSYMBOL_TYPE (msymbol))
    {
    case mst_file_text:
    case mst_file_data:
    case mst_file_bss:
      if (sfile == NULL
	  || filename_cmp (msymbol->filename, sfile) == 0)
	{
	  file_symbol.minsym = msymbol;
	  file_symbol.objfile = objfile;
	}
      break;

    case mst_solib_trampoline:

      /* If a trampoline symbol is found, we prefer to keep
	 looking for the *real* symbol.  If the actual symbol
	 is not found, then we'll use the trampoline
	 entry.  */
      if (trampoline_symbol.minsym == NULL)
	{
	  trampoline_symbol.minsym = msymbol;
	  trampoline_symbol.objfile = objfile;
	}
      break;

    case mst_unknown:
    default:
      external_symbol.minsym = msymbol;
      external_symbol.objfile = objfile;
      /* We have the real symbol.  No use looking further.  */
      return true;
    }

  /* Keep looking.  */
  return false;
}
Ejemplo n.º 19
0
int
new_logical_line_flags (const char *fname, /* DON'T destroy it!  We point to it!  */
			int line_number,
			int flags)
{
  switch (flags)
    {
    case 0:
      break;
    case 1:
      if (line_number != -1)
	abort ();
      break;
    case 1 << 1:
    case 1 << 2:
      /* FIXME: we could check that include nesting is correct.  */
      break;
    default:
      abort ();
    }

  if (line_number >= 0)
    logical_input_line = line_number;
  else if (line_number == -1 && fname && !*fname && (flags & (1 << 2)))
    {
      logical_input_file = physical_input_file;
      logical_input_line = physical_input_line;
      fname = NULL;
    }

  if (fname
      && (logical_input_file == NULL
	  || filename_cmp (logical_input_file, fname)))
    {
      logical_input_file = fname;
      return 1;
    }
  else
    return 0;
}
Ejemplo n.º 20
0
static void
handle_pragma_implementation (cpp_reader* /*dfile*/)
{
  tree fname = parse_strconst_pragma ("implementation", 1);
  const char *filename;
  struct impl_files *ifiles = impl_file_chain;

  if (fname == error_mark_node)
    return;

  if (fname == 0)
    {
      if (main_input_filename)
	filename = main_input_filename;
      else
	filename = LOCATION_FILE (input_location);
      filename = lbasename (filename);
    }
  else
    {
      filename = TREE_STRING_POINTER (fname);
      if (cpp_included_before (parse_in, filename, input_location))
	warning (0, "#pragma implementation for %qs appears after "
		 "file is included", filename);
    }

  for (; ifiles; ifiles = ifiles->next)
    {
      if (! filename_cmp (ifiles->filename, filename))
	break;
    }
  if (ifiles == 0)
    {
      ifiles = XNEW (struct impl_files);
      ifiles->filename = xstrdup (filename);
      ifiles->next = impl_file_chain;
      impl_file_chain = ifiles;
    }
Ejemplo n.º 21
0
Archivo: listing.c Proyecto: CromFr/gdb
static file_info_type *
file_info (const char *file_name)
{
  /* Find an entry with this file name.  */
  file_info_type *p = file_info_head;

  while (p != (file_info_type *) NULL)
    {
      if (filename_cmp (p->filename, file_name) == 0)
	return p;
      p = p->next;
    }

  /* Make new entry.  */
  p = (file_info_type *) xmalloc (sizeof (file_info_type));
  p->next = file_info_head;
  file_info_head = p;
  p->filename = xstrdup (file_name);
  p->pos = 0;
  p->linenum = 0;
  p->at_end = 0;

  return p;
}
Ejemplo n.º 22
0
/* Function to display source in the source window.  */
enum tui_status
tui_set_source_content (struct symtab *s, 
			int line_no,
			int noerror)
{
  enum tui_status ret = TUI_FAILURE;

  if (s != (struct symtab *) NULL)
    {
      FILE *stream;
      int i, desc, c, line_width, nlines;
      char *src_line = 0;

      if ((ret = tui_alloc_source_buffer (TUI_SRC_WIN)) == TUI_SUCCESS)
	{
	  line_width = TUI_SRC_WIN->generic.width - 1;
	  /* Take hilite (window border) into account, when
	     calculating the number of lines.  */
	  nlines = (line_no + (TUI_SRC_WIN->generic.height - 2)) - line_no;
	  desc = open_source_file (s);
	  if (desc < 0)
	    {
	      if (!noerror)
		{
		  char *name = alloca (strlen (s->filename) + 100);

		  sprintf (name, "%s:%d", s->filename, line_no);
		  print_sys_errmsg (name, errno);
		}
	      ret = TUI_FAILURE;
	    }
	  else
	    {
	      if (s->line_charpos == 0)
		find_source_lines (s, desc);

	      if (line_no < 1 || line_no > s->nlines)
		{
		  close (desc);
		  printf_unfiltered (
			  "Line number %d out of range; %s has %d lines.\n",
				      line_no, s->filename, s->nlines);
		}
	      else if (lseek (desc, s->line_charpos[line_no - 1], 0) < 0)
		{
		  close (desc);
		  perror_with_name (s->filename);
		}
	      else
		{
		  int offset, cur_line_no, cur_line, cur_len, threshold;
		  struct tui_gen_win_info *locator
		    = tui_locator_win_info_ptr ();
                  struct tui_source_info *src
		    = &TUI_SRC_WIN->detail.source_info;

                  if (TUI_SRC_WIN->generic.title)
                    xfree (TUI_SRC_WIN->generic.title);
                  TUI_SRC_WIN->generic.title = xstrdup (s->filename);

                  if (src->filename)
                    xfree (src->filename);
                  src->filename = xstrdup (s->filename);

		  /* Determine the threshold for the length of the
                     line and the offset to start the display.  */
		  offset = src->horizontal_offset;
		  threshold = (line_width - 1) + offset;
		  stream = fdopen (desc, FOPEN_RT);
		  clearerr (stream);
		  cur_line = 0;
		  src->gdbarch = get_objfile_arch (s->objfile);
		  src->start_line_or_addr.loa = LOA_LINE;
		  cur_line_no = src->start_line_or_addr.u.line_no = line_no;
		  if (offset > 0)
		    src_line = (char *) xmalloc (
					   (threshold + 1) * sizeof (char));
		  while (cur_line < nlines)
		    {
		      struct tui_win_element *element
			= (struct tui_win_element *)
			TUI_SRC_WIN->generic.content[cur_line];

		      /* Get the first character in the line.  */
		      c = fgetc (stream);

		      if (offset == 0)
			src_line = ((struct tui_win_element *)
				   TUI_SRC_WIN->generic.content[
					cur_line])->which_element.source.line;
		      /* Init the line with the line number.  */
		      sprintf (src_line, "%-6d", cur_line_no);
		      cur_len = strlen (src_line);
		      i = cur_len - ((cur_len / tui_default_tab_len ())
				     * tui_default_tab_len ());
		      while (i < tui_default_tab_len ())
			{
			  src_line[cur_len] = ' ';
			  i++;
			  cur_len++;
			}
		      src_line[cur_len] = (char) 0;

		      /* Set whether element is the execution point
		         and whether there is a break point on it.  */
		      element->which_element.source.line_or_addr.loa =
			LOA_LINE;
		      element->which_element.source.line_or_addr.u.line_no =
			cur_line_no;
		      element->which_element.source.is_exec_point =
			(filename_cmp (((struct tui_win_element *)
				       locator->content[0])->which_element.locator.file_name,
				       s->filename) == 0
			 && cur_line_no == ((struct tui_win_element *)
					    locator->content[0])->which_element.locator.line_no);
		      if (c != EOF)
			{
			  i = strlen (src_line) - 1;
			  do
			    {
			      if ((c != '\n') && (c != '\r') 
				  && (++i < threshold))
				{
				  if (c < 040 && c != '\t')
				    {
				      src_line[i++] = '^';
				      src_line[i] = c + 0100;
				    }
				  else if (c == 0177)
				    {
				      src_line[i++] = '^';
				      src_line[i] = '?';
				    }
				  else
				    { /* Store the charcter in the
					 line buffer.  If it is a tab,
					 then translate to the correct
					 number of chars so we don't
					 overwrite our buffer.  */
				      if (c == '\t')
					{
					  int j, max_tab_len
					    = tui_default_tab_len ();

					  for (j = i - ((i / max_tab_len)
							* max_tab_len);
					       j < max_tab_len
						 && i < threshold;
					       i++, j++)
					    src_line[i] = ' ';
					  i--;
					}
				      else
					src_line[i] = c;
				    }
				  src_line[i + 1] = 0;
				}
			      else
				{ /* If we have not reached EOL, then
				     eat chars until we do.  */
				  while (c != EOF && c != '\n' && c != '\r')
				    c = fgetc (stream);
				  /* Handle non-'\n' end-of-line.  */
				  if (c == '\r' 
				      && (c = fgetc (stream)) != '\n' 
				      && c != EOF)
				    {
				       ungetc (c, stream);
				       c = '\r';
				    }
				  
				}
			    }
			  while (c != EOF && c != '\n' && c != '\r' 
				 && i < threshold 
				 && (c = fgetc (stream)));
			}
		      /* Now copy the line taking the offset into
			 account.  */
		      if (strlen (src_line) > offset)
			strcpy (((struct tui_win_element *)
				 TUI_SRC_WIN->generic.content[cur_line])->which_element.source.line,
				&src_line[offset]);
		      else
			((struct tui_win_element *)
			 TUI_SRC_WIN->generic.content[
			  cur_line])->which_element.source.line[0] = (char) 0;
		      cur_line++;
		      cur_line_no++;
		    }
		  if (offset > 0)
		    xfree (src_line);
		  fclose (stream);
		  TUI_SRC_WIN->generic.content_size = nlines;
		  ret = TUI_SUCCESS;
		}
	    }
	}
    }
  return ret;
}
Ejemplo n.º 23
0
int
filename_eq (const void *s1, const void *s2)
{
  /* The casts are for -Wc++-compat.  */
  return filename_cmp ((const char *) s1, (const char *) s2) == 0;
}
Ejemplo n.º 24
0
void
vfinfo (FILE *fp, const char *fmt, va_list ap, bfd_boolean is_warning)
{
  bfd_boolean fatal = FALSE;
  const char *scan;
  int arg_type;
  unsigned int arg_count = 0;
  unsigned int arg_no;
  union vfinfo_args
  {
    int i;
    long l;
    void *p;
    bfd_vma v;
    struct {
      bfd *abfd;
      asection *sec;
      bfd_vma off;
    } reladdr;
    enum
      {
	Bad,
	Int,
	Long,
	Ptr,
	Vma,
	RelAddr
      } type;
  } args[9];

  for (arg_no = 0; arg_no < sizeof (args) / sizeof (args[0]); arg_no++)
    args[arg_no].type = Bad;

  arg_count = 0;
  scan = fmt;
  while (*scan != '\0')
    {
      while (*scan != '%' && *scan != '\0')
	scan++;

      if (*scan == '%')
	{
	  scan++;

	  arg_no = arg_count;
	  if (*scan != '0' && ISDIGIT (*scan) && scan[1] == '$')
	    {
	      arg_no = *scan - '1';
	      scan += 2;
	    }

	  arg_type = Bad;
	  switch (*scan++)
	    {
	    case '\0':
	      --scan;
	      break;

	    case 'V':
	    case 'v':
	    case 'W':
	      arg_type = Vma;
	      break;

	    case 's':
	      arg_type = Ptr;
	      break;

	    case 'p':
	      if (*scan == 'A' || *scan == 'B' || *scan == 'I'
		  || *scan == 'R' || *scan == 'S' || *scan ==  'T')
		scan++;
	      arg_type = Ptr;
	      break;

	    case 'C':
	    case 'D':
	    case 'G':
	    case 'H':
	      arg_type = RelAddr;
	      break;

	    case 'd':
	    case 'u':
	      arg_type = Int;
	      break;

	    case 'l':
	      if (*scan == 'd' || *scan == 'u')
		{
		  ++scan;
		  arg_type = Long;
		}
	      break;

	    default:
	      break;
	    }
	  if (arg_type != Bad)
	    {
	      if (arg_no >= sizeof (args) / sizeof (args[0]))
		abort ();
	      args[arg_no].type = arg_type;
	      ++arg_count;
	    }
	}
    }

  for (arg_no = 0; arg_no < arg_count; arg_no++)
    {
      switch (args[arg_no].type)
	{
	case Int:
	  args[arg_no].i = va_arg (ap, int);
	  break;
	case Long:
	  args[arg_no].l = va_arg (ap, long);
	  break;
	case Ptr:
	  args[arg_no].p = va_arg (ap, void *);
	  break;
	case Vma:
	  args[arg_no].v = va_arg (ap, bfd_vma);
	  break;
	case RelAddr:
	  args[arg_no].reladdr.abfd = va_arg (ap, bfd *);
	  args[arg_no].reladdr.sec = va_arg (ap, asection *);
	  args[arg_no].reladdr.off = va_arg (ap, bfd_vma);
	  break;
	default:
	  abort ();
	}
    }

  arg_count = 0;
  while (*fmt != '\0')
    {
      const char *str = fmt;
      while (*fmt != '%' && *fmt != '\0')
	fmt++;
      if (fmt != str)
	if (fwrite (str, 1, fmt - str, fp))
	  {
	    /* Ignore.  */
	  }

      if (*fmt == '%')
	{
	  fmt++;

	  arg_no = arg_count;
	  if (*fmt != '0' && ISDIGIT (*fmt) && fmt[1] == '$')
	    {
	      arg_no = *fmt - '1';
	      fmt += 2;
	    }

	  switch (*fmt++)
	    {
	    case '\0':
	      --fmt;
	      /* Fall through.  */

	    case '%':
	      /* literal % */
	      putc ('%', fp);
	      break;

	    case 'X':
	      /* no object output, fail return */
	      config.make_executable = FALSE;
	      break;

	    case 'V':
	      /* hex bfd_vma */
	      {
		bfd_vma value = args[arg_no].v;
		++arg_count;
		fprintf_vma (fp, value);
	      }
	      break;

	    case 'v':
	      /* hex bfd_vma, no leading zeros */
	      {
		char buf[100];
		char *p = buf;
		bfd_vma value = args[arg_no].v;
		++arg_count;
		sprintf_vma (p, value);
		while (*p == '0')
		  p++;
		if (!*p)
		  p--;
		fputs (p, fp);
	      }
	      break;

	    case 'W':
	      /* hex bfd_vma with 0x with no leading zeroes taking up
		 8 spaces.  */
	      {
		char buf[100];
		bfd_vma value;
		char *p;
		int len;

		value = args[arg_no].v;
		++arg_count;
		sprintf_vma (buf, value);
		for (p = buf; *p == '0'; ++p)
		  ;
		if (*p == '\0')
		  --p;
		len = strlen (p);
		while (len < 8)
		  {
		    putc (' ', fp);
		    ++len;
		  }
		fprintf (fp, "0x%s", p);
	      }
	      break;

	    case 'F':
	      /* Error is fatal.  */
	      fatal = TRUE;
	      break;

	    case 'P':
	      /* Print program name.  */
	      fprintf (fp, "%s", program_name);
	      break;

	    case 'E':
	      /* current bfd error or errno */
	      fprintf (fp, "%s", bfd_errmsg (bfd_get_error ()));
	      break;

	    case 'C':
	    case 'D':
	    case 'G':
	    case 'H':
	      /* Clever filename:linenumber with function name if possible.
		 The arguments are a BFD, a section, and an offset.  */
	      {
		static bfd *last_bfd;
		static char *last_file;
		static char *last_function;
		bfd *abfd;
		asection *section;
		bfd_vma offset;
		asymbol **asymbols = NULL;
		const char *filename;
		const char *functionname;
		unsigned int linenumber;
		bfd_boolean discard_last;
		bfd_boolean done;

		abfd = args[arg_no].reladdr.abfd;
		section = args[arg_no].reladdr.sec;
		offset = args[arg_no].reladdr.off;
		++arg_count;

		if (abfd != NULL)
		  {
		    if (!bfd_generic_link_read_symbols (abfd))
		      einfo (_("%F%P: %pB: could not read symbols: %E\n"), abfd);

		    asymbols = bfd_get_outsymbols (abfd);
		  }

		/* The GNU Coding Standard requires that error messages
		   be of the form:

		     source-file-name:lineno: message

		   We do not always have a line number available so if
		   we cannot find them we print out the section name and
		   offset instead.  */
		discard_last = TRUE;
		if (abfd != NULL
		    && bfd_find_nearest_line (abfd, section, asymbols, offset,
					      &filename, &functionname,
					      &linenumber))
		  {
		    if (functionname != NULL
			&& (fmt[-1] == 'C' || fmt[-1] == 'H'))
		      {
			/* Detect the case where we are printing out a
			   message for the same function as the last
			   call to vinfo ("%C").  In this situation do
			   not print out the ABFD filename or the
			   function name again.  Note - we do still
			   print out the source filename, as this will
			   allow programs that parse the linker's output
			   (eg emacs) to correctly locate multiple
			   errors in the same source file.  */
			if (last_bfd == NULL
			    || last_function == NULL
			    || last_bfd != abfd
			    || (last_file == NULL) != (filename == NULL)
			    || (filename != NULL
				&& filename_cmp (last_file, filename) != 0)
			    || strcmp (last_function, functionname) != 0)
			  {
			    lfinfo (fp, _("%pB: in function `%pT':\n"),
				    abfd, functionname);

			    last_bfd = abfd;
			    if (last_file != NULL)
			      free (last_file);
			    last_file = NULL;
			    if (filename)
			      last_file = xstrdup (filename);
			    if (last_function != NULL)
			      free (last_function);
			    last_function = xstrdup (functionname);
			  }
			discard_last = FALSE;
		      }
		    else
		      lfinfo (fp, "%pB:", abfd);

		    if (filename != NULL)
		      fprintf (fp, "%s:", filename);

		    done = fmt[-1] != 'H';
		    if (functionname != NULL && fmt[-1] == 'G')
		      lfinfo (fp, "%pT", functionname);
		    else if (filename != NULL && linenumber != 0)
		      fprintf (fp, "%u%s", linenumber, done ? "" : ":");
		    else
		      done = FALSE;
		  }
		else
		  {
		    lfinfo (fp, "%pB:", abfd);
		    done = FALSE;
		  }
		if (!done)
		  lfinfo (fp, "(%pA+0x%v)", section, offset);

		if (discard_last)
		  {
		    last_bfd = NULL;
		    if (last_file != NULL)
		      {
			free (last_file);
			last_file = NULL;
		      }
		    if (last_function != NULL)
		      {
			free (last_function);
			last_function = NULL;
		      }
		  }
	      }
	      break;

	    case 'p':
	      if (*fmt == 'A')
		{
		  /* section name from a section */
		  asection *sec;
		  bfd *abfd;
		  const char *group = NULL;
		  struct coff_comdat_info *ci;

		  fmt++;
		  sec = (asection *) args[arg_no].p;
		  ++arg_count;
		  abfd = sec->owner;
		  fprintf (fp, "%s", sec->name);
		  if (abfd != NULL
		      && bfd_get_flavour (abfd) == bfd_target_elf_flavour
		      && elf_next_in_group (sec) != NULL
		      && (sec->flags & SEC_GROUP) == 0)
		    group = elf_group_name (sec);
		  else if (abfd != NULL
			   && bfd_get_flavour (abfd) == bfd_target_coff_flavour
			   && (ci = bfd_coff_get_comdat_section (sec->owner,
								 sec)) != NULL)
		    group = ci->name;
		  if (group != NULL)
		    fprintf (fp, "[%s]", group);
		}
	      else if (*fmt == 'B')
		{
		  /* filename from a bfd */
		  bfd *abfd = (bfd *) args[arg_no].p;

		  fmt++;
		  ++arg_count;
		  if (abfd == NULL)
		    fprintf (fp, "%s generated", program_name);
		  else if (abfd->my_archive != NULL
			   && !bfd_is_thin_archive (abfd->my_archive))
		    fprintf (fp, "%s(%s)", abfd->my_archive->filename,
			     abfd->filename);
		  else
		    fprintf (fp, "%s", abfd->filename);
		}
	      else if (*fmt == 'I')
		{
		  /* filename from a lang_input_statement_type */
		  lang_input_statement_type *i;

		  fmt++;
		  i = (lang_input_statement_type *) args[arg_no].p;
		  ++arg_count;
		  if (i->the_bfd != NULL
		      && i->the_bfd->my_archive != NULL
		      && !bfd_is_thin_archive (i->the_bfd->my_archive))
		    fprintf (fp, "(%s)%s", i->the_bfd->my_archive->filename,
			     i->local_sym_name);
		  else
		    fprintf (fp, "%s", i->filename);
		}
	      else if (*fmt == 'R')
		{
		  /* Print all that's interesting about a relent.  */
		  arelent *relent = (arelent *) args[arg_no].p;

		  fmt++;
		  ++arg_count;
		  lfinfo (fp, "%s+0x%v (type %s)",
			  (*(relent->sym_ptr_ptr))->name,
			  relent->addend,
			  relent->howto->name);
		}
	      else if (*fmt == 'S')
		{
		  /* Print script file and linenumber.  */
		  etree_type node;
		  etree_type *tp = (etree_type *) args[arg_no].p;

		  fmt++;
		  ++arg_count;
		  if (tp == NULL)
		    {
		      tp = &node;
		      tp->type.filename = ldlex_filename ();
		      tp->type.lineno = lineno;
		    }
		  if (tp->type.filename != NULL)
		    fprintf (fp, "%s:%u", tp->type.filename, tp->type.lineno);
		}
	      else if (*fmt == 'T')
		{
		  /* Symbol name.  */
		  const char *name = (const char *) args[arg_no].p;

		  fmt++;
		  ++arg_count;
		  if (name == NULL || *name == 0)
		    {
		      fprintf (fp, _("no symbol"));
		      break;
		    }
		  else if (demangling)
		    {
		      char *demangled;

		      demangled = bfd_demangle (link_info.output_bfd, name,
						DMGL_ANSI | DMGL_PARAMS);
		      if (demangled != NULL)
			{
			  fprintf (fp, "%s", demangled);
			  free (demangled);
			  break;
			}
		    }
		  fprintf (fp, "%s", name);
		}
	      else
		{
		  /* native (host) void* pointer, like printf */
		  fprintf (fp, "%p", args[arg_no].p);
		  ++arg_count;
		}
	      break;

	    case 's':
	      /* arbitrary string, like printf */
	      fprintf (fp, "%s", (char *) args[arg_no].p);
	      ++arg_count;
	      break;

	    case 'd':
	      /* integer, like printf */
	      fprintf (fp, "%d", args[arg_no].i);
	      ++arg_count;
	      break;

	    case 'u':
	      /* unsigned integer, like printf */
	      fprintf (fp, "%u", args[arg_no].i);
	      ++arg_count;
	      break;

	    case 'l':
	      if (*fmt == 'd')
		{
		  fprintf (fp, "%ld", args[arg_no].l);
		  ++arg_count;
		  ++fmt;
		  break;
		}
	      else if (*fmt == 'u')
		{
		  fprintf (fp, "%lu", args[arg_no].l);
		  ++arg_count;
		  ++fmt;
		  break;
		}
	      /* Fallthru */

	    default:
	      fprintf (fp, "%%%c", fmt[-1]);
	      break;
	    }
	}
    }

  if (is_warning && config.fatal_warnings)
    config.make_executable = FALSE;

  if (fatal)
    xexit (1);
}
Ejemplo n.º 25
0
const struct line_map *
linemap_add (struct line_maps *set, enum lc_reason reason,
	     unsigned int sysp, const char *to_file, linenum_type to_line)
{
  struct line_map *map;
  source_location start_location = set->highest_location + 1;

  if (set->used && start_location < set->maps[set->used - 1].start_location)
    abort ();

  if (set->used == set->allocated)
    {
      line_map_realloc reallocator
	= set->reallocator ? set->reallocator : xrealloc;
      set->allocated = 2 * set->allocated + 256;
      set->maps
	= (struct line_map *) (*reallocator) (set->maps,
					      set->allocated
					      * sizeof (struct line_map));
      memset (&set->maps[set->used], 0, ((set->allocated - set->used)
					 * sizeof (struct line_map)));
    }

  map = &set->maps[set->used];

  if (to_file && *to_file == '\0' && reason != LC_RENAME_VERBATIM)
    to_file = "<stdin>";

  if (reason == LC_RENAME_VERBATIM)
    reason = LC_RENAME;

  if (set->depth == 0 && reason == LC_RENAME)
    abort ();

  if (reason == LC_LEAVE)
    {
      struct line_map *from;
      bool error;

      if (MAIN_FILE_P (map - 1))
	{
	  if (to_file == NULL)
	    {
	      set->depth--;
	      return NULL;
	    }
	  error = true;
          reason = LC_RENAME;
          from = map - 1;
	}
      else
	{
	  from = INCLUDED_FROM (set, map - 1);
	  error = to_file && filename_cmp (from->to_file, to_file);
	}

      /* Depending upon whether we are handling preprocessed input or
	 not, this can be a user error or an ICE.  */
      if (error)
	fprintf (stderr, "line-map.c: file \"%s\" left but not entered\n",
		 to_file);

      /* A TO_FILE of NULL is special - we use the natural values.  */
      if (error || to_file == NULL)
	{
	  to_file = from->to_file;
	  to_line = SOURCE_LINE (from, from[1].start_location);
	  sysp = from->sysp;
	}
    }

  map->reason = reason;
  map->sysp = sysp;
  map->start_location = start_location;
  map->to_file = to_file;
  map->to_line = to_line;
  set->cache = set->used++;
  map->column_bits = 0;
  set->highest_location = start_location;
  set->highest_line = start_location;
  set->max_column_hint = 0;

  if (reason == LC_ENTER)
    {
      map->included_from = set->depth == 0 ? -1 : (int) (set->used - 2);
      set->depth++;
      if (set->trace_includes)
	trace_include (set, map);
    }
  else if (reason == LC_RENAME)
    map->included_from = map[-1].included_from;
  else if (reason == LC_LEAVE)
    {
      set->depth--;
      map->included_from = INCLUDED_FROM (set, map - 1)->included_from;
    }

  return map;
}
Ejemplo n.º 26
0
static void
read_function_mappings (const char *filename)
{
  FILE * file = fopen (filename, "r");
  char dummy[1024];
  int count = 0;
  unsigned int i;

  if (!file)
    {
      fprintf (stderr, _("%s: could not open %s.\n"), whoami, filename);
      done (1);
    }

  /* First parse the mapping file so we know how big we need to
     make our tables.  We also do some sanity checks at this
     time.  */
  while (!feof (file))
    {
      int matches;

      matches = fscanf (file, "%[^\n:]", dummy);
      if (!matches)
	parse_error (filename);

      /* Just skip messages about files with no symbols.  */
      if (!strncmp (dummy, "No symbols in ", 14))
	{
	  matches = fscanf (file, "\n");
	  if (matches == EOF)
	    parse_error (filename);
	  continue;
	}

      /* Don't care what else is on this line at this point.  */
      matches = fscanf (file, "%[^\n]\n", dummy);
      if (!matches)
	parse_error (filename);
      count++;
    }

  /* Now we know how big we need to make our table.  */
  symbol_map = ((struct function_map *)
		xmalloc (count * sizeof (struct function_map)));

  /* Rewind the input file so we can read it again.  */
  rewind (file);

  /* Read each entry and put it into the table.  */
  count = 0;
  while (!feof (file))
    {
      int matches;
      char *tmp;

      matches = fscanf (file, "%[^\n:]", dummy);
      if (!matches)
	parse_error (filename);

      /* Just skip messages about files with no symbols.  */
      if (!strncmp (dummy, "No symbols in ", 14))
	{
	  matches = fscanf (file, "\n");
	  if (matches == EOF)
	    parse_error (filename);
	  continue;
	}

      /* dummy has the filename, go ahead and copy it.  */
      symbol_map[count].file_name = (char *) xmalloc (strlen (dummy) + 1);
      strcpy (symbol_map[count].file_name, dummy);

      /* Now we need the function name.  */
      matches = fscanf (file, "%[^\n]\n", dummy);
      if (!matches)
	parse_error (filename);
      tmp = strrchr (dummy, ' ') + 1;
      symbol_map[count].function_name = (char *) xmalloc (strlen (tmp) + 1);
      strcpy (symbol_map[count].function_name, tmp);
      count++;
    }

  /* Record the size of the map table for future reference.  */
  symbol_map_count = count;

  for (i = 0; i < symbol_map_count; ++i)
    if (i == 0
        || filename_cmp (symbol_map[i].file_name, symbol_map[i - 1].file_name))
      symbol_map[i].is_first = 1;

  qsort (symbol_map, symbol_map_count, sizeof (struct function_map), cmp_symbol_map);
}
Ejemplo n.º 27
0
static unsigned int
get_filenum (const char *filename, unsigned int num)
{
  static unsigned int last_used, last_used_dir_len;
  const char *file;
  size_t dir_len;
  unsigned int i, dir;

  if (num == 0 && last_used)
    {
      if (! files[last_used].dir
	  && filename_cmp (filename, files[last_used].filename) == 0)
	return last_used;
      if (files[last_used].dir
	  && filename_ncmp (filename, dirs[files[last_used].dir],
			    last_used_dir_len) == 0
	  && IS_DIR_SEPARATOR (filename [last_used_dir_len])
	  && filename_cmp (filename + last_used_dir_len + 1,
			   files[last_used].filename) == 0)
	return last_used;
    }

  file = lbasename (filename);
  /* Don't make empty string from / or A: from A:/ .  */
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
  if (file <= filename + 3)
    file = filename;
#else
  if (file == filename + 1)
    file = filename;
#endif
  dir_len = file - filename;

  dir = 0;
  if (dir_len)
    {
#ifndef DWARF2_DIR_SHOULD_END_WITH_SEPARATOR
      --dir_len;
#endif
      for (dir = 1; dir < dirs_in_use; ++dir)
	if (filename_ncmp (filename, dirs[dir], dir_len) == 0
	    && dirs[dir][dir_len] == '\0')
	  break;

      if (dir >= dirs_in_use)
	{
	  if (dir >= dirs_allocated)
	    {
	      dirs_allocated = dir + 32;
	      dirs = (char **)
		     xrealloc (dirs, (dir + 32) * sizeof (const char *));
	    }

	  dirs[dir] = (char *) xmalloc (dir_len + 1);
	  memcpy (dirs[dir], filename, dir_len);
	  dirs[dir][dir_len] = '\0';
	  dirs_in_use = dir + 1;
	}
    }

  if (num == 0)
    {
      for (i = 1; i < files_in_use; ++i)
	if (files[i].dir == dir
	    && files[i].filename
	    && filename_cmp (file, files[i].filename) == 0)
	  {
	    last_used = i;
	    last_used_dir_len = dir_len;
	    return i;
	  }
    }
  else
    i = num;

  if (i >= files_allocated)
    {
      unsigned int old = files_allocated;

      files_allocated = i + 32;
      files = (struct file_entry *)
	xrealloc (files, (i + 32) * sizeof (struct file_entry));

      memset (files + old, 0, (i + 32 - old) * sizeof (struct file_entry));
    }

  files[i].filename = num ? file : xstrdup (file);
  files[i].dir = dir;
  if (files_in_use < i + 1)
    files_in_use = i + 1;
  last_used = i;
  last_used_dir_len = dir_len;

  return i;
}
Ejemplo n.º 28
0
const struct line_map *
linemap_add (struct line_maps *set, enum lc_reason reason,
	     unsigned int sysp, const char *to_file, linenum_type to_line)
{
  struct line_map *map;
  source_location start_location = set->highest_location + 1;

  linemap_assert (!(LINEMAPS_ORDINARY_USED (set)
		    && (start_location
			< MAP_START_LOCATION (LINEMAPS_LAST_ORDINARY_MAP (set)))));

  /* When we enter the file for the first time reason cannot be
     LC_RENAME.  */
  linemap_assert (!(set->depth == 0 && reason == LC_RENAME));

  /* If we are leaving the main file, return a NULL map.  */
  if (reason == LC_LEAVE
      && MAIN_FILE_P (LINEMAPS_LAST_ORDINARY_MAP (set))
      && to_file == NULL)
    {
      set->depth--;
      return NULL;
    }

  map = new_linemap (set, reason);

  if (to_file && *to_file == '\0' && reason != LC_RENAME_VERBATIM)
    to_file = "<stdin>";

  if (reason == LC_RENAME_VERBATIM)
    reason = LC_RENAME;

  if (reason == LC_LEAVE)
    {
      /* When we are just leaving an "included" file, and jump to the next
	 location inside the "includer" right after the #include
	 "included", this variable points the map in use right before the
	 #include "included", inside the same "includer" file.  */
      struct line_map *from;
      bool error;

      if (MAIN_FILE_P (map - 1))
	{
	  /* So this _should_ means we are leaving the main file --
	     effectively ending the compilation unit. But to_file not
	     being NULL means the caller thinks we are leaving to
	     another file. This is an erroneous behaviour but we'll
	     try to recover from it. Let's pretend we are not leaving
	     the main file.  */
	  error = true;
          reason = LC_RENAME;
          from = map - 1;
	}
      else
	{
	  /* (MAP - 1) points to the map we are leaving. The
	     map from which (MAP - 1) got included should be the map
	     that comes right before MAP in the same file.  */
	  from = INCLUDED_FROM (set, map - 1);
	  error = to_file && filename_cmp (ORDINARY_MAP_FILE_NAME (from),
					   to_file);
	}

      /* Depending upon whether we are handling preprocessed input or
	 not, this can be a user error or an ICE.  */
      if (error)
	fprintf (stderr, "line-map.c: file \"%s\" left but not entered\n",
		 to_file);

      /* A TO_FILE of NULL is special - we use the natural values.  */
      if (error || to_file == NULL)
	{
	  to_file = ORDINARY_MAP_FILE_NAME (from);
	  to_line = SOURCE_LINE (from, from[1].start_location);
	  sysp = ORDINARY_MAP_IN_SYSTEM_HEADER_P (from);
	}
    }

  linemap_assert (reason != LC_ENTER_MACRO);
  ORDINARY_MAP_IN_SYSTEM_HEADER_P (map) = sysp;
  MAP_START_LOCATION (map) = start_location;
  ORDINARY_MAP_FILE_NAME (map) = to_file;
  ORDINARY_MAP_STARTING_LINE_NUMBER (map) = to_line;
  LINEMAPS_ORDINARY_CACHE (set) = LINEMAPS_ORDINARY_USED (set) - 1;
  ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map) = 0;
  set->highest_location = start_location;
  set->highest_line = start_location;
  set->max_column_hint = 0;

  if (reason == LC_ENTER)
    {
      ORDINARY_MAP_INCLUDER_FILE_INDEX (map) = 
	set->depth == 0 ? -1 : (int) (LINEMAPS_ORDINARY_USED (set) - 2);
      set->depth++;
      if (set->trace_includes)
	trace_include (set, map);
    }
  else if (reason == LC_RENAME)
    ORDINARY_MAP_INCLUDER_FILE_INDEX (map) =
      ORDINARY_MAP_INCLUDER_FILE_INDEX (&map[-1]);
  else if (reason == LC_LEAVE)
    {
      set->depth--;
      ORDINARY_MAP_INCLUDER_FILE_INDEX (map) =
	ORDINARY_MAP_INCLUDER_FILE_INDEX (INCLUDED_FROM (set, map - 1));
    }

  return map;
}
Ejemplo n.º 29
0
void
core_create_line_syms (void)
{
  char *prev_name, *prev_filename;
  unsigned int prev_name_len, prev_filename_len;
  bfd_vma vma, min_vma = ~(bfd_vma) 0, max_vma = 0;
  Sym *prev, dummy, *sym;
  const char *filename;
  int prev_line_num;
  Sym_Table ltab;
  bfd_vma vma_high;

  /* Create symbols for functions as usual.  This is necessary in
     cases where parts of a program were not compiled with -g.  For
     those parts we still want to get info at the function level.  */
  core_create_function_syms ();

  /* Pass 1: count the number of symbols.  */

  /* To find all line information, walk through all possible
     text-space addresses (one by one!) and get the debugging
     info for each address.  When the debugging info changes,
     it is time to create a new symbol.

     Of course, this is rather slow and it would be better if
     BFD would provide an iterator for enumerating all line infos.  */
  prev_name_len = PATH_MAX;
  prev_filename_len = PATH_MAX;
  prev_name = (char *) xmalloc (prev_name_len);
  prev_filename = (char *) xmalloc (prev_filename_len);
  ltab.len = 0;
  prev_line_num = 0;

  vma_high = core_text_sect->vma + bfd_get_section_size (core_text_sect);
  for (vma = core_text_sect->vma; vma < vma_high; vma += min_insn_size)
    {
      unsigned int len;

      if (!get_src_info (vma, &filename, &dummy.name, &dummy.line_num)
	  || (prev_line_num == dummy.line_num
	      && prev_name != NULL
	      && strcmp (prev_name, dummy.name) == 0
	      && filename_cmp (prev_filename, filename) == 0))
	continue;

      ++ltab.len;
      prev_line_num = dummy.line_num;

      len = strlen (dummy.name);
      if (len >= prev_name_len)
	{
	  prev_name_len = len + 1024;
	  free (prev_name);
	  prev_name = (char *) xmalloc (prev_name_len);
	}

      strcpy (prev_name, dummy.name);
      len = strlen (filename);

      if (len >= prev_filename_len)
	{
	  prev_filename_len = len + 1024;
	  free (prev_filename);
	  prev_filename = (char *) xmalloc (prev_filename_len);
	}

      strcpy (prev_filename, filename);

      min_vma = MIN (vma, min_vma);
      max_vma = MAX (vma, max_vma);
    }

  free (prev_name);
  free (prev_filename);

  /* Make room for function symbols, too.  */
  ltab.len += symtab.len;
  ltab.base = (Sym *) xmalloc (ltab.len * sizeof (Sym));
  ltab.limit = ltab.base;

  /* Pass 2 - create symbols.  */

  /* We now set is_static as we go along, rather than by running
     through the symbol table at the end.

     The old way called symtab_finalize before the is_static pass,
     causing a problem since symtab_finalize uses is_static as part of
     its address conflict resolution algorithm.  Since global symbols
     were prefered over static symbols, and all line symbols were
     global at that point, static function names that conflicted with
     their own line numbers (static, but labeled as global) were
     rejected in favor of the line num.

     This was not the desired functionality.  We always want to keep
     our function symbols and discard any conflicting line symbols.
     Perhaps symtab_finalize should be modified to make this
     distinction as well, but the current fix works and the code is a
     lot cleaner now.  */
  prev = 0;

  for (vma = core_text_sect->vma; vma < vma_high; vma += min_insn_size)
    {
      sym_init (ltab.limit);

      if (!get_src_info (vma, &filename, &ltab.limit->name, &ltab.limit->line_num)
	  || (prev && prev->line_num == ltab.limit->line_num
	      && strcmp (prev->name, ltab.limit->name) == 0
	      && filename_cmp (prev->file->name, filename) == 0))
	continue;

      /* Make name pointer a malloc'ed string.  */
      ltab.limit->name = xstrdup (ltab.limit->name);
      ltab.limit->file = source_file_lookup_path (filename);

      ltab.limit->addr = vma;

      /* Set is_static based on the enclosing function, using either:
	 1) the previous symbol, if it's from the same function, or
	 2) a symtab lookup.  */
      if (prev && ltab.limit->file == prev->file &&
	  strcmp (ltab.limit->name, prev->name) == 0)
	{
	  ltab.limit->is_static = prev->is_static;
	}
      else
	{
	  sym = sym_lookup(&symtab, ltab.limit->addr);
          if (sym)
	    ltab.limit->is_static = sym->is_static;
	}

      prev = ltab.limit;

      DBG (AOUTDEBUG, printf ("[core_create_line_syms] %lu %s 0x%lx\n",
			      (unsigned long) (ltab.limit - ltab.base),
			      ltab.limit->name,
			      (unsigned long) ltab.limit->addr));
      ++ltab.limit;
    }

  /* Copy in function symbols.  */
  memcpy (ltab.limit, symtab.base, symtab.len * sizeof (Sym));
  ltab.limit += symtab.len;

  if ((unsigned int) (ltab.limit - ltab.base) != ltab.len)
    {
      fprintf (stderr,
	       _("%s: somebody miscounted: ltab.len=%d instead of %ld\n"),
	       whoami, ltab.len, (long) (ltab.limit - ltab.base));
      done (1);
    }

  /* Finalize ltab and make it symbol table.  */
  symtab_finalize (&ltab);
  free (symtab.base);
  symtab = ltab;
}
Ejemplo n.º 30
0
Archivo: listing.c Proyecto: CromFr/gdb
void
listing_newline (char *ps)
{
  char *file;
  unsigned int line;
  static unsigned int last_line = 0xffff;
  static char *last_file = NULL;
  list_info_type *new_i = NULL;

  if (listing == 0)
    return;

  if (now_seg == absolute_section)
    return;

#ifdef OBJ_ELF
  /* In ELF, anything in a section beginning with .debug or .line is
     considered to be debugging information.  This includes the
     statement which switches us into the debugging section, which we
     can only set after we are already in the debugging section.  */
  if ((listing & LISTING_NODEBUG) != 0
      && listing_tail != NULL
      && ! listing_tail->debugging)
    {
      const char *segname;

      segname = segment_name (now_seg);
      if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0
	  || strncmp (segname, ".line", sizeof ".line" - 1) == 0)
	listing_tail->debugging = 1;
    }
#endif

  as_where (&file, &line);
  if (ps == NULL)
    {
      if (line == last_line
	  && !(last_file && file && filename_cmp (file, last_file)))
	return;

      new_i = (list_info_type *) xmalloc (sizeof (list_info_type));

      /* Detect if we are reading from stdin by examining the file
	 name returned by as_where().

	 [FIXME: We rely upon the name in the strcmp below being the
	 same as the one used by input_scrub_new_file(), if that is
	 not true, then this code will fail].

	 If we are reading from stdin, then we need to save each input
	 line here (assuming of course that we actually have a line of
	 input to read), so that it can be displayed in the listing
	 that is produced at the end of the assembly.  */
      if (strcmp (file, _("{standard input}")) == 0
	  && input_line_pointer != NULL)
	{
	  char *copy;
	  int len;
	  int seen_quote = 0;
	  int seen_slash = 0;

	  for (copy = input_line_pointer;
	       *copy && (seen_quote
			 || is_end_of_line [(unsigned char) *copy] != 1);
	       copy++)
	    {
	      if (seen_slash)
		seen_slash = 0;
	      else if (*copy == '\\')
		seen_slash = 1;
	      else if (*copy == '"')
		seen_quote = !seen_quote;
	    }

	  len = copy - input_line_pointer + 1;

	  copy = (char *) xmalloc (len);

	  if (copy != NULL)
	    {
	      char *src = input_line_pointer;
	      char *dest = copy;

	      while (--len)
		{
		  unsigned char c = *src++;

		  /* Omit control characters in the listing.  */
		  if (!ISCNTRL (c))
		    *dest++ = c;
		}

	      *dest = 0;
	    }

	  new_i->line_contents = copy;
	}
      else
	new_i->line_contents = NULL;
    }
  else
    {
      new_i = (list_info_type *) xmalloc (sizeof (list_info_type));
      new_i->line_contents = ps;
    }

  last_line = line;
  last_file = file;

  new_frag ();

  if (listing_tail)
    listing_tail->next = new_i;
  else
    head = new_i;

  listing_tail = new_i;

  new_i->frag = frag_now;
  new_i->line = line;
  new_i->file = file_info (file);
  new_i->next = (list_info_type *) NULL;
  new_i->messages = NULL;
  new_i->last_message = NULL;
  new_i->edict = EDICT_NONE;
  new_i->hll_file = (file_info_type *) NULL;
  new_i->hll_line = 0;
  new_i->debugging = 0;

  new_frag ();

#ifdef OBJ_ELF
  /* In ELF, anything in a section beginning with .debug or .line is
     considered to be debugging information.  */
  if ((listing & LISTING_NODEBUG) != 0)
    {
      const char *segname;

      segname = segment_name (now_seg);
      if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0
	  || strncmp (segname, ".line", sizeof ".line" - 1) == 0)
	new_i->debugging = 1;
    }
#endif
}