+ return true;
+}
+
+/* See source-cache.h. */
+
+bool
+source_cache::get_line_charpos (struct symtab *s,
+ const std::vector<off_t> **offsets)
+{
+ std::string fullname = symtab_to_fullname (s);
+
+ auto iter = m_offset_cache.find (fullname);
+ if (iter == m_offset_cache.end ())
+ {
+ if (!ensure (s))
+ return false;
+ iter = m_offset_cache.find (fullname);
+ /* cache_source_text ensured this was entered. */
+ gdb_assert (iter != m_offset_cache.end ());
+ }
+
+ *offsets = &iter->second;
+ return true;
+}
+
+/* A helper function that extracts the desired source lines from TEXT,
+ putting them into LINES_OUT. The arguments are as for
+ get_source_lines. Returns true on success, false if the line
+ numbers are invalid. */
+
+static bool
+extract_lines (const std::string &text, int first_line, int last_line,
+ std::string *lines_out)
+{
+ int lineno = 1;
+ std::string::size_type pos = 0;
+ std::string::size_type first_pos = std::string::npos;
+
+ while (pos != std::string::npos && lineno <= last_line)
+ {
+ std::string::size_type new_pos = text.find ('\n', pos);
+
+ if (lineno == first_line)
+ first_pos = pos;
+
+ pos = new_pos;
+ if (lineno == last_line || pos == std::string::npos)
+ {
+ /* A newline at the end does not start a new line. */
+ if (first_pos == std::string::npos
+ || first_pos == text.size ())
+ return false;
+ if (pos == std::string::npos)
+ pos = text.size ();
+ else
+ ++pos;
+ *lines_out = text.substr (first_pos, pos - first_pos);
+ return true;