aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2/read.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/dwarf2/read.c')
-rw-r--r--gdb/dwarf2/read.c209
1 files changed, 209 insertions, 0 deletions
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 523663e..85bbef8 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -101,6 +101,8 @@
#include "extract-store-integer.h"
#include "inferior.h"
#include "debuginfod-support.h"
+#include "exceptions.h"
+#include "gdbsupport/scoped_mmap.h"
/* When == 1, print basic high level tracing messages.
When > 1, be more verbose.
@@ -1967,6 +1969,213 @@ dw2_get_file_names (dwarf2_per_cu_data *this_cu,
return this_cu->file_names;
}
+#if !HAVE_SYS_MMAN_H
+
+bool
+mapped_debug_line::contains_matching_filename
+ (gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher)
+{
+ return false;
+}
+
+gdb::array_view<const gdb_byte>
+mapped_debug_line::read_debug_line_separate
+ (const char *filename, std::unique_ptr<index_cache_resource> *resource)
+{
+ return {};
+}
+
+bool
+mapped_debug_line::read_debug_line_from_debuginfod (objfile *objfile)
+{
+ return false;
+}
+
+void
+mapped_debug_line::map_filenames
+ (gdb::function_view<symbol_filename_ftype> fun,
+ bool need_fullname)
+{
+ return;
+}
+
+#else /* !HAVE_SYS_MMAN_H */
+
+struct line_resource_mmap final : public index_cache_resource
+{
+ /* Try to mmap FILENAME. Throw an exception on failure, including if the
+ file doesn't exist. */
+ line_resource_mmap (const char *filename)
+ : mapping (mmap_file (filename))
+ {}
+
+ scoped_mmap mapping;
+};
+
+/* See read.h. */
+
+bool
+mapped_debug_line::contains_matching_filename
+ (gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher)
+{
+ for (line_header_up &lh : line_headers)
+ for (file_entry &fe : lh->file_names ())
+ {
+ const char *filename = fe.name;
+
+ if (file_matcher (fe.name, false))
+ return true;
+
+ bool basename_match = file_matcher (lbasename (fe.name), true);
+
+ if (!basenames_may_differ && !basename_match)
+ continue;
+
+ /* DW_AT_comp_dir is not explicitly mentioned in the .debug_line
+ until DWARF5. Since we don't have access to the CU at this
+ point we just check for a partial match on the filename.
+ If there is a match, the full debuginfo will be downloaded
+ ane the match will be re-evalute with DW_AT_comp_dir. */
+ if (lh->version < 5 && fe.d_index == 0)
+ return basename_match;
+
+ const char *dirname = fe.include_dir (&*lh);
+ std::string fullname;
+
+ if (dirname == nullptr || IS_ABSOLUTE_PATH (filename))
+ fullname = filename;
+ else
+ fullname = std::string (dirname) + SLASH_STRING + filename;
+
+ gdb::unique_xmalloc_ptr<char> rewritten
+ = rewrite_source_path (fullname.c_str ());
+ if (rewritten != nullptr)
+ fullname = rewritten.release ();
+
+ if (file_matcher (fullname.c_str (), false))
+ return true;
+ }
+
+ return false;
+}
+
+/* See read.h. */
+
+void
+mapped_debug_line::map_filenames
+ (gdb::function_view<symbol_filename_ftype> fun,
+ bool need_fullname)
+{
+ for (line_header_up &lh : line_headers)
+ for (file_entry &fe : lh->file_names ())
+ {
+ const char *filename = fe.name;
+
+ if (!need_fullname)
+ {
+ fun (filename, nullptr);
+ continue;
+ }
+
+ const char *dirname = fe.include_dir (&*lh);
+ std::string fullname;
+
+ if (dirname == nullptr || IS_ABSOLUTE_PATH (filename))
+ fullname = filename;
+ else
+ fullname = std::string (dirname) + SLASH_STRING + filename;
+
+ gdb::unique_xmalloc_ptr<char> rewritten
+ = rewrite_source_path (fullname.c_str ());
+ if (rewritten != nullptr)
+ fullname = rewritten.release ();
+
+ fun (filename, fullname.c_str ());
+ }
+}
+
+/* See read.h. */
+
+gdb::array_view<const gdb_byte>
+mapped_debug_line::read_debug_line_separate
+ (const char *filename, std::unique_ptr<index_cache_resource> *resource)
+{
+ if (filename == nullptr)
+ return {};
+
+ try
+ {
+ line_resource_mmap *mmap_resource
+ = new line_resource_mmap (filename);
+
+ resource->reset (mmap_resource);
+
+ return gdb::array_view<const gdb_byte>
+ ((const gdb_byte *) mmap_resource->mapping.get (),
+ mmap_resource->mapping.size ());
+ }
+ catch (const gdb_exception &except)
+ {
+ exception_print (gdb_stderr, except);
+ }
+
+ return {};
+}
+
+/* See read.h. */
+
+bool
+mapped_debug_line::read_debug_line_from_debuginfod (objfile *objfile)
+{
+ const bfd_build_id *build_id = build_id_bfd_get (objfile->obfd.get ());
+ if (build_id == nullptr)
+ return false;
+
+ gdb::unique_xmalloc_ptr<char> line_path;
+ scoped_fd line_fd = debuginfod_section_query (build_id->data,
+ build_id->size,
+ bfd_get_filename
+ (objfile->obfd.get ()),
+ ".debug_line",
+ &line_path);
+
+ if (line_fd.get () < 0)
+ return false;
+
+ gdb::unique_xmalloc_ptr<char> line_str_path;
+ scoped_fd line_str_fd = debuginfod_section_query (build_id->data,
+ build_id->size,
+ bfd_get_filename
+ (objfile->obfd.get ()),
+ ".debug_line_str",
+ &line_str_path);
+
+ line_data = read_debug_line_separate (line_path.get (), &line_resource);
+ line_str_data = read_debug_line_separate (line_str_path.get (),
+ &line_str_resource);
+
+ const gdb_byte *line_ptr = line_data.data ();
+
+ while (line_ptr < line_data.data () + line_data.size ())
+ {
+ line_header_up lh
+ = dwarf_decode_line_header (objfile->obfd.get (),
+ line_data, line_str_data,
+ &line_ptr, false,
+ nullptr, nullptr);
+ line_headers.emplace_back (std::move (lh));
+ }
+
+ return true;
+}
+#endif /* !HAVE_SYS_MMAN_H */
+
+mapped_debug_line::mapped_debug_line (objfile *objfile)
+{
+ if (!read_debug_line_from_debuginfod (objfile))
+ line_headers.clear ();
+}
+
/* A helper for the "quick" functions which computes and caches the
real path for a given file name from the line table. */