diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/buildsym.c | 36 | ||||
-rw-r--r-- | gdb/buildsym.h | 39 | ||||
-rw-r--r-- | gdb/dwarf2/cu.c | 17 | ||||
-rw-r--r-- | gdb/dwarf2/line-header.c | 18 | ||||
-rw-r--r-- | gdb/dwarf2/line-header.h | 6 | ||||
-rw-r--r-- | gdb/dwarf2/read.c | 58 | ||||
-rw-r--r-- | gdb/macroscope.c | 2 | ||||
-rw-r--r-- | gdb/symfile.c | 4 | ||||
-rw-r--r-- | gdb/symfile.h | 11 | ||||
-rw-r--r-- | gdb/symtab.h | 14 | ||||
-rw-r--r-- | gdb/xcoffread.c | 1 |
11 files changed, 148 insertions, 58 deletions
diff --git a/gdb/buildsym.c b/gdb/buildsym.c index fae3d5ef4c..67d88a94ba 100644 --- a/gdb/buildsym.c +++ b/gdb/buildsym.c @@ -52,6 +52,7 @@ struct pending_block buildsym_compunit::buildsym_compunit (struct objfile *objfile_, const char *name, const char *comp_dir_, + const char *name_for_id, enum language language_, CORE_ADDR last_addr) : m_objfile (objfile_), @@ -70,7 +71,7 @@ buildsym_compunit::buildsym_compunit (struct objfile *objfile_, It can happen that the debug info provides a different path to NAME than DIRNAME,NAME. We cope with this in watch_main_source_file_lossage but that only works if the main_subfile doesn't have a symtab yet. */ - start_subfile (name); + start_subfile (name, name_for_id); /* Save this so that we don't have to go looking for it at the end of the subfiles list. */ m_main_subfile = m_current_subfile; @@ -483,40 +484,38 @@ buildsym_compunit::make_blockvector () return (blockvector); } - -/* Start recording information about source code that came from an - included (or otherwise merged-in) source file with a different - name. NAME is the name of the file (cannot be NULL). */ + +/* See buildsym.h. */ void -buildsym_compunit::start_subfile (const char *name) +buildsym_compunit::start_subfile (const char *name, const char *name_for_id) { /* See if this subfile is already registered. */ - symtab_create_debug_printf ("name = %s", name); + symtab_create_debug_printf ("name = %s, name_for_id = %s", name, name_for_id); for (subfile *subfile = m_subfiles; subfile; subfile = subfile->next) { std::string subfile_name_holder; - const char *subfile_name; + const char *subfile_name_for_id; /* If NAME is an absolute path, and this subfile is not, then attempt to create an absolute path to compare. */ - if (IS_ABSOLUTE_PATH (name) - && !IS_ABSOLUTE_PATH (subfile->name) + if (IS_ABSOLUTE_PATH (name_for_id) + && !IS_ABSOLUTE_PATH (subfile->name_for_id) && !m_comp_dir.empty ()) { subfile_name_holder = path_join (m_comp_dir.c_str (), - subfile->name.c_str ()); - subfile_name = subfile_name_holder.c_str (); + subfile->name_for_id.c_str ()); + subfile_name_for_id = subfile_name_holder.c_str (); } else - subfile_name = subfile->name.c_str (); + subfile_name_for_id = subfile->name_for_id.c_str (); - if (FILENAME_CMP (subfile_name, name) == 0) + if (FILENAME_CMP (subfile_name_for_id, name_for_id) == 0) { - symtab_create_debug_printf ("found existing symtab with name %s (%s)", - subfile->name.c_str (), subfile_name); + symtab_create_debug_printf ("found existing symtab with name_for_id %s (%s)", + subfile->name_for_id.c_str (), subfile_name_for_id); m_current_subfile = subfile; return; } @@ -526,6 +525,7 @@ buildsym_compunit::start_subfile (const char *name) subfile_up subfile (new struct subfile); subfile->name = name; + subfile->name_for_id = name_for_id; m_current_subfile = subfile.get (); @@ -595,6 +595,7 @@ buildsym_compunit::patch_subfile_names (struct subfile *subfile, { m_comp_dir = std::move (subfile->name); subfile->name = name; + subfile->name_for_id = name; set_last_source_file (name); /* Default the source language to whatever can be deduced from @@ -932,7 +933,8 @@ buildsym_compunit::end_compunit_symtab_with_blockvector /* Allocate a symbol table if necessary. */ if (subfile->symtab == NULL) - subfile->symtab = allocate_symtab (cu, subfile->name.c_str ()); + subfile->symtab = allocate_symtab (cu, subfile->name.c_str (), + subfile->name_for_id.c_str ()); struct symtab *symtab = subfile->symtab; diff --git a/gdb/buildsym.h b/gdb/buildsym.h index 2ad0033626..a42317aded 100644 --- a/gdb/buildsym.h +++ b/gdb/buildsym.h @@ -55,6 +55,12 @@ struct subfile struct subfile *next = nullptr; std::string name; + + /* This field is analoguous in function to symtab::filename_for_id. + + It is used to look up existing subfiles in calls to start_subfile. */ + std::string name_for_id; + std::vector<linetable_entry> line_vector_entries; enum language language = language_unknown; struct symtab *symtab = nullptr; @@ -135,12 +141,24 @@ struct buildsym_compunit { /* Start recording information about a primary source file (IOW, not an included source file). + COMP_DIR is the directory in which the compilation unit was compiled - (or NULL if not known). */ + (or NULL if not known). + + NAME and NAME_FOR_ID have the same purpose as for the start_subfile + method. */ + + buildsym_compunit (struct objfile *objfile_, const char *name, + const char *comp_dir_, const char *name_for_id, + enum language language_, CORE_ADDR last_addr); + + /* Same as above, but passes NAME for NAME_FOR_ID. */ buildsym_compunit (struct objfile *objfile_, const char *name, const char *comp_dir_, enum language language_, - CORE_ADDR last_addr); + CORE_ADDR last_addr) + : buildsym_compunit (objfile_, name, comp_dir_, name, language_, last_addr) + {} /* Reopen an existing compunit_symtab so that additional symbols can be added to it. Arguments are as for the main constructor. CUST @@ -198,7 +216,22 @@ struct buildsym_compunit void record_block_range (struct block *block, CORE_ADDR start, CORE_ADDR end_inclusive); - void start_subfile (const char *name); + /* Start recording information about source code that comes from a source + file. This sets the current subfile, creating it if necessary. + + NAME is the user-visible name of the subfile. + + NAME_FOR_ID is a name that must be stable between the different calls to + start_subfile referring to the same file (it is used for looking up + existing subfiles). It can be equal to NAME if NAME follows that rule. */ + void start_subfile (const char *name, const char *name_for_id); + + /* Same as above, but passes NAME for NAME_FOR_ID. */ + + void start_subfile (const char *name) + { + return start_subfile (name, name); + } void patch_subfile_names (struct subfile *subfile, const char *name); diff --git a/gdb/dwarf2/cu.c b/gdb/dwarf2/cu.c index d40dd094b0..fe95d7ea87 100644 --- a/gdb/dwarf2/cu.c +++ b/gdb/dwarf2/cu.c @@ -21,6 +21,8 @@ #include "dwarf2/cu.h" #include "dwarf2/read.h" #include "objfiles.h" +#include "filenames.h" +#include "gdbsupport/pathstuff.h" /* Initialize dwarf2_cu to read PER_CU, in the context of PER_OBJFILE. */ @@ -60,9 +62,22 @@ dwarf2_cu::start_compunit_symtab (const char *name, const char *comp_dir, { gdb_assert (m_builder == nullptr); + std::string name_for_id_holder; + const char *name_for_id = name; + + /* Prepend the compilation directory to the filename if needed (if not + absolute already) to get the "name for id" for our main symtab. The name + for the main file coming from the line table header will be generated using + the same logic, so will hopefully match what we pass here. */ + if (!IS_ABSOLUTE_PATH (name) && comp_dir != nullptr) + { + name_for_id_holder = path_join (comp_dir, name); + name_for_id = name_for_id_holder.c_str (); + } + m_builder.reset (new struct buildsym_compunit (this->per_objfile->objfile, - name, comp_dir, lang (), low_pc)); + name, comp_dir, name_for_id, lang (), low_pc)); list_in_scope = get_builder ()->get_file_symbols (); diff --git a/gdb/dwarf2/line-header.c b/gdb/dwarf2/line-header.c index a1bd39df7e..73db3765c0 100644 --- a/gdb/dwarf2/line-header.c +++ b/gdb/dwarf2/line-header.c @@ -62,14 +62,22 @@ line_header::file_file_name (const file_entry &fe) const { gdb_assert (is_valid_file_index (fe.index)); - if (IS_ABSOLUTE_PATH (fe.name)) - return fe.name; + std::string ret = fe.name; + + if (IS_ABSOLUTE_PATH (ret)) + return ret; const char *dir = fe.include_dir (this); - if (dir == nullptr) - return fe.name; + if (dir != nullptr) + ret = path_join (dir, ret); + + if (IS_ABSOLUTE_PATH (ret)) + return ret; + + if (m_comp_dir != nullptr) + ret = path_join (m_comp_dir, ret); - return path_join (dir, fe.name); + return ret; } static void diff --git a/gdb/dwarf2/line-header.h b/gdb/dwarf2/line-header.h index e6b52f7520..e7a63a3791 100644 --- a/gdb/dwarf2/line-header.h +++ b/gdb/dwarf2/line-header.h @@ -171,8 +171,10 @@ struct line_header header. These point into dwarf2_per_objfile->line_buffer. */ const gdb_byte *statement_program_start {}, *statement_program_end {}; - /* Return file name relative to the compilation directory of file - FE in this object's file name table. */ + /* Return the most "complete" file name for FILE possible. + + This means prepending the directory and compilation directory, as needed, + until we get an absolute path. */ std::string file_file_name (const file_entry &fe) const; /* Return the compilation directory of the compilation unit in the context of diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index b6d9f5a8aa..ae0b5d7a77 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -956,8 +956,8 @@ static void dwarf_decode_lines (struct line_header *, struct dwarf2_cu *, CORE_ADDR, int decode_mapping); -static void dwarf2_start_subfile (struct dwarf2_cu *, const char *, - const char *); +static void dwarf2_start_subfile (dwarf2_cu *cu, const file_entry &fe, + const line_header &lh); static struct symbol *new_symbol (struct die_info *, struct type *, struct dwarf2_cu *, struct symbol * = NULL); @@ -9439,7 +9439,10 @@ find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu) && producer_is_gcc_lt_4_3 (cu) && res.get_name () != nullptr && IS_ABSOLUTE_PATH (res.get_name ())) - res.set_comp_dir (ldirname (res.get_name ())); + { + res.set_comp_dir (ldirname (res.get_name ())); + res.set_name (make_unique_xstrdup (lbasename (res.get_name ()))); + } cu->per_cu->fnd.reset (new file_and_directory (std::move (res))); return *cu->per_cu->fnd; @@ -9700,18 +9703,20 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die) for (i = 0; i < file_names.size (); ++i) { file_entry &fe = file_names[i]; - dwarf2_start_subfile (this, fe.name, - fe.include_dir (line_header)); + dwarf2_start_subfile (this, fe, *line_header); buildsym_compunit *b = get_builder (); - if (b->get_current_subfile ()->symtab == NULL) + subfile *sf = b->get_current_subfile (); + + if (sf->symtab == nullptr) { /* NOTE: start_subfile will recognize when it's been passed a file it has already seen. So we can't assume there's a simple mapping from cu->line_header->file_names to subfiles, plus cu->line_header->file_names may contain dups. */ - const char *name = b->get_current_subfile ()->name.c_str (); - b->get_current_subfile ()->symtab = allocate_symtab (cust, name); + const char *name = sf->name.c_str (); + const char *name_for_id = sf->name_for_id.c_str (); + sf->symtab = allocate_symtab (cust, name, name_for_id); } fe.symtab = b->get_current_subfile ()->symtab; @@ -20021,11 +20026,9 @@ lnp_state_machine::handle_set_file (file_name_index file) dwarf2_debug_line_missing_file_complaint (); else { - const char *dir = fe->include_dir (m_line_header); - m_last_subfile = m_cu->get_builder ()->get_current_subfile (); m_line_has_non_zero_discriminator = m_discriminator != 0; - dwarf2_start_subfile (m_cu, fe->name, dir); + dwarf2_start_subfile (m_cu, *fe, *m_line_header); } } @@ -20308,7 +20311,7 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu, const file_entry *fe = state_machine.current_file (); if (fe != NULL) - dwarf2_start_subfile (cu, fe->name, fe->include_dir (lh)); + dwarf2_start_subfile (cu, *fe, *lh); /* Decode the table. */ while (line_ptr < line_end && !end_sequence) @@ -20520,14 +20523,14 @@ dwarf_decode_lines (struct line_header *lh, struct dwarf2_cu *cu, for (auto &fe : lh->file_names ()) { - dwarf2_start_subfile (cu, fe.name, fe.include_dir (lh)); - if (builder->get_current_subfile ()->symtab == NULL) - { - builder->get_current_subfile ()->symtab - = allocate_symtab (cust, - builder->get_current_subfile ()->name.c_str ()); - } - fe.symtab = builder->get_current_subfile ()->symtab; + dwarf2_start_subfile (cu, fe, *lh); + subfile *sf = builder->get_current_subfile (); + + if (sf->symtab == nullptr) + sf->symtab = allocate_symtab (cust, sf->name.c_str (), + sf->name_for_id.c_str ()); + + fe.symtab = sf->symtab; } } @@ -20555,10 +20558,12 @@ dwarf_decode_lines (struct line_header *lh, struct dwarf2_cu *cu, subfile's name. */ static void -dwarf2_start_subfile (struct dwarf2_cu *cu, const char *filename, - const char *dirname) +dwarf2_start_subfile (dwarf2_cu *cu, const file_entry &fe, + const line_header &lh) { - std::string copy; + std::string filename_holder; + const char *filename = fe.name; + const char *dirname = lh.include_dir_at (fe.d_index); /* In order not to lose the line information directory, we concatenate it to the filename when it makes sense. @@ -20569,11 +20574,12 @@ dwarf2_start_subfile (struct dwarf2_cu *cu, const char *filename, if (!IS_ABSOLUTE_PATH (filename) && dirname != NULL) { - copy = path_join (dirname, filename); - filename = copy.c_str (); + filename_holder = path_join (dirname, filename); + filename = filename_holder.c_str (); } - cu->get_builder ()->start_subfile (filename); + std::string filename_for_id = lh.file_file_name (fe); + cu->get_builder ()->start_subfile (filename, filename_for_id.c_str ()); } static void diff --git a/gdb/macroscope.c b/gdb/macroscope.c index 93f561accc..fe7f10e296 100644 --- a/gdb/macroscope.c +++ b/gdb/macroscope.c @@ -51,7 +51,7 @@ sal_macro_scope (struct symtab_and_line sal) gdb::unique_xmalloc_ptr<struct macro_scope> ms (XNEW (struct macro_scope)); main_file = macro_main (cust->macro_table ()); - inclusion = macro_lookup_inclusion (main_file, sal.symtab->filename); + inclusion = macro_lookup_inclusion (main_file, sal.symtab->filename_for_id); if (inclusion) { diff --git a/gdb/symfile.c b/gdb/symfile.c index 27e9571832..aea8c762ee 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -2772,13 +2772,15 @@ deduce_language_from_filename (const char *filename) CUST is from the result of allocate_compunit_symtab. */ struct symtab * -allocate_symtab (struct compunit_symtab *cust, const char *filename) +allocate_symtab (struct compunit_symtab *cust, const char *filename, + const char *filename_for_id) { struct objfile *objfile = cust->objfile (); struct symtab *symtab = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct symtab); symtab->filename = objfile->intern (filename); + symtab->filename_for_id = objfile->intern (filename_for_id); symtab->fullname = NULL; symtab->set_language (deduce_language_from_filename (filename)); diff --git a/gdb/symfile.h b/gdb/symfile.h index f44dfa060a..5216e85c4e 100644 --- a/gdb/symfile.h +++ b/gdb/symfile.h @@ -201,9 +201,18 @@ extern symfile_segment_data_up default_symfile_segments (bfd *abfd); extern bfd_byte *default_symfile_relocate (struct objfile *objfile, asection *sectp, bfd_byte *buf); -extern struct symtab *allocate_symtab (struct compunit_symtab *, const char *) +extern struct symtab *allocate_symtab + (struct compunit_symtab *cust, const char *filename, const char *id) ATTRIBUTE_NONNULL (1); +/* Same as the above, but passes FILENAME for ID. */ + +static inline struct symtab * +allocate_symtab (struct compunit_symtab *cust, const char *filename) +{ + return allocate_symtab (cust, filename, filename); +} + extern struct compunit_symtab *allocate_compunit_symtab (struct objfile *, const char *) ATTRIBUTE_NONNULL (1); diff --git a/gdb/symtab.h b/gdb/symtab.h index 4bc86645e2..89d7a183ff 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -1644,10 +1644,22 @@ struct symtab struct linetable *m_linetable; - /* Name of this source file. This pointer is never NULL. */ + /* Name of this source file, in a form appropriate to print to the user. + + This pointer is never nullptr. */ const char *filename; + /* Filename for this source file, used as an identifier to link with + related objects such as associated macro_source_file objects. It must + therefore match the name of any macro_source_file object created for this + source file. The value can be the same as FILENAME if it is known to + follow that rule, or another form of the same file name, this is up to + the specific debug info reader. + + This pointer is never nullptr.*/ + const char *filename_for_id; + /* Language of this source file. */ enum language m_language; diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c index bcb667b29e..6be0a7c446 100644 --- a/gdb/xcoffread.c +++ b/gdb/xcoffread.c @@ -714,6 +714,7 @@ process_linenos (CORE_ADDR start, CORE_ADDR end) } struct subfile *current_subfile = get_current_subfile (); current_subfile->name = inclTable[ii].name; + current_subfile->name_for_id = inclTable[ii].name; #endif start_subfile (pop_subfile ()); |