-\f
-/* Create and initialize the table S->line_charpos that records
- the positions of the lines in the source file, which is assumed
- to be open on descriptor DESC.
- All set S->nlines to the number of such lines. */
-
-void
-find_source_lines (struct symtab *s, int desc)
-{
- struct stat st;
- char *p, *end;
- int nlines = 0;
- int lines_allocated = 1000;
- int *line_charpos;
- long mtime = 0;
- int size;
-
- gdb_assert (s);
- line_charpos = XNEWVEC (int, lines_allocated);
- if (fstat (desc, &st) < 0)
- perror_with_name (symtab_to_filename_for_display (s));
-
- if (SYMTAB_OBJFILE (s) != NULL && SYMTAB_OBJFILE (s)->obfd != NULL)
- mtime = SYMTAB_OBJFILE (s)->mtime;
- else if (exec_bfd)
- mtime = exec_bfd_mtime;
-
- if (mtime && mtime < st.st_mtime)
- warning (_("Source file is more recent than executable."));
-
- {
- /* st_size might be a large type, but we only support source files whose
- size fits in an int. */
- size = (int) st.st_size;
-
- /* Use the heap, not the stack, because this may be pretty large,
- and we may run into various kinds of limits on stack size. */
- gdb::def_vector<char> data (size);
-
- /* Reassign `size' to result of read for systems where \r\n -> \n. */
- size = myread (desc, data.data (), size);
- if (size < 0)
- perror_with_name (symtab_to_filename_for_display (s));
- end = data.data () + size;
- p = &data[0];
- line_charpos[0] = 0;
- nlines = 1;
- while (p != end)
- {
- if (*p++ == '\n'
- /* A newline at the end does not start a new line. */
- && p != end)
- {
- if (nlines == lines_allocated)
- {
- lines_allocated *= 2;
- line_charpos =
- (int *) xrealloc ((char *) line_charpos,
- sizeof (int) * lines_allocated);
- }
- line_charpos[nlines++] = p - data.data ();
- }
- }
- }
-
- s->nlines = nlines;
- s->line_charpos =
- (int *) xrealloc ((char *) line_charpos, nlines * sizeof (int));
-
-}
-
-\f
-
-/* Get full pathname and line number positions for a symtab.
- Set *FULLNAME to actual name of the file as found by `openp',
- or to 0 if the file is not found. */
-
-static void
-get_filename_and_charpos (struct symtab *s)
-{
- scoped_fd desc = open_source_file (s);
- if (desc.get () < 0)
- return;
- if (s->line_charpos == 0)
- find_source_lines (s, desc.get ());
-}
-
-/* See source.h. */
-
-int
-identify_source_line (struct symtab *s, int line, int mid_statement,
- CORE_ADDR pc)
-{
- if (s->line_charpos == 0)
- get_filename_and_charpos (s);
- if (s->fullname == 0)
- return 0;
- if (line > s->nlines)
- /* Don't index off the end of the line_charpos array. */
- return 0;
- annotate_source (s->fullname, line, s->line_charpos[line - 1],
- mid_statement, get_objfile_arch (SYMTAB_OBJFILE (s)), pc);