From ddc01737d34f16074b2c9a92c5a808be5c91340f Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Tue, 26 Apr 2022 21:40:51 -0400 Subject: [PATCH] gdb/dwarf: pass compilation directory to line header The following patch changes line_header::file_file_name to prepend the compilation directory to the file name, if needed. For that, the line header needs to know about the compilation directory. Prepare for that by adding a constructor that takes it as a parameter, and passing the value down everywhere needed. Add a second constructor for the special case of building a line_header for doing a hash table lookup, since that case doesn't require a compilation directory value. Change-Id: Iba3ba0293e4e2d13a64b257cf9a3094684d54330 --- gdb/dwarf2/line-header.c | 5 +++-- gdb/dwarf2/line-header.h | 26 +++++++++++++++++++++++--- gdb/dwarf2/read.c | 27 +++++++++++++++------------ 3 files changed, 41 insertions(+), 17 deletions(-) diff --git a/gdb/dwarf2/line-header.c b/gdb/dwarf2/line-header.c index 63230847568..13379851b9b 100644 --- a/gdb/dwarf2/line-header.c +++ b/gdb/dwarf2/line-header.c @@ -264,7 +264,8 @@ line_header_up dwarf_decode_line_header (sect_offset sect_off, bool is_dwz, dwarf2_per_objfile *per_objfile, struct dwarf2_section_info *section, - const struct comp_unit_head *cu_header) + const struct comp_unit_head *cu_header, + const char *comp_dir) { const gdb_byte *line_ptr; unsigned int bytes_read, offset_size; @@ -281,7 +282,7 @@ dwarf_decode_line_header (sect_offset sect_off, bool is_dwz, return 0; } - line_header_up lh (new line_header ()); + line_header_up lh (new line_header (comp_dir)); lh->sect_off = sect_off; lh->offset_in_dwz = is_dwz; diff --git a/gdb/dwarf2/line-header.h b/gdb/dwarf2/line-header.h index 59b317d0d72..32f52c4a647 100644 --- a/gdb/dwarf2/line-header.h +++ b/gdb/dwarf2/line-header.h @@ -68,8 +68,18 @@ struct file_entry which contains the following information. */ struct line_header { - line_header () - : offset_in_dwz {} + /* COMP_DIR is the value of the DW_AT_comp_dir attribute of the compilation + unit in the context of which we are reading this line header, or nullptr + if unknown or not applicable. */ + explicit line_header (const char *comp_dir) + : offset_in_dwz {}, m_comp_dir (comp_dir) + {} + + /* This constructor should only be used to create line_header intances to do + hash table lookups. */ + line_header (sect_offset sect_off, bool offset_in_dwz) + : sect_off (sect_off), + offset_in_dwz (offset_in_dwz) {} /* Add an entry to the include directory table. */ @@ -161,6 +171,11 @@ struct line_header number FILE in this object's file name table. */ std::string file_file_name (int file) const; + /* Return the compilation directory of the compilation unit in the context of + which this line header is read. Return nullptr if non applicable. */ + const char *comp_dir () const + { return m_comp_dir; } + private: /* The include_directories table. Note these are observing pointers. The memory is owned by debug_line_buffer. */ @@ -171,6 +186,10 @@ struct line_header before, and is 0 in DWARF 5 and later). So the client should use file_name_at method for access. */ std::vector m_file_names; + + /* Compilation directory of the compilation unit in the context of which this + line header is read. nullptr if unknown or not applicable. */ + const char *m_comp_dir = nullptr; }; typedef std::unique_ptr line_header_up; @@ -191,6 +210,7 @@ file_entry::include_dir (const line_header *lh) const extern line_header_up dwarf_decode_line_header (sect_offset sect_off, bool is_dwz, dwarf2_per_objfile *per_objfile, - struct dwarf2_section_info *section, const struct comp_unit_head *cu_header); + struct dwarf2_section_info *section, const struct comp_unit_head *cu_header, + const char *comp_dir); #endif /* DWARF2_LINE_HEADER_H */ diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 70419da13e4..b6d9f5a8aa1 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -949,7 +949,8 @@ static struct die_info *die_specification (struct die_info *die, struct dwarf2_cu **); static line_header_up dwarf_decode_line_header (sect_offset sect_off, - struct dwarf2_cu *cu); + struct dwarf2_cu *cu, + const char *comp_dir); static void dwarf_decode_lines (struct line_header *, struct dwarf2_cu *, @@ -2746,6 +2747,8 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader, line_header_up lh; sect_offset line_offset {}; + file_and_directory &fnd = find_file_and_directory (comp_unit_die, cu); + attr = dwarf2_attr (comp_unit_die, DW_AT_stmt_list, cu); if (attr != nullptr && attr->form_is_unsigned ()) { @@ -2765,11 +2768,9 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader, return; } - lh = dwarf_decode_line_header (line_offset, cu); + lh = dwarf_decode_line_header (line_offset, cu, fnd.get_comp_dir ()); } - file_and_directory &fnd = find_file_and_directory (comp_unit_die, cu); - int offset = 0; if (!fnd.is_unknown ()) ++offset; @@ -9451,11 +9452,11 @@ find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu) static void handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu, + const file_and_directory &fnd, CORE_ADDR lowpc) /* ARI: editCase function */ { dwarf2_per_objfile *per_objfile = cu->per_objfile; struct attribute *attr; - struct line_header line_header_local; hashval_t line_header_local_hash; void **slot; int decode_mapping; @@ -9484,8 +9485,7 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu, xcalloc, xfree)); } - line_header_local.sect_off = line_offset; - line_header_local.offset_in_dwz = cu->per_cu->is_dwz; + line_header line_header_local (line_offset, cu->per_cu->is_dwz); line_header_local_hash = line_header_hash (&line_header_local); if (per_objfile->line_header_hash != NULL) { @@ -9506,7 +9506,8 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu, /* dwarf_decode_line_header does not yet provide sufficient information. We always have to call also dwarf_decode_lines for it. */ - line_header_up lh = dwarf_decode_line_header (line_offset, cu); + line_header_up lh = dwarf_decode_line_header (line_offset, cu, + fnd.get_comp_dir ()); if (lh == NULL) return; @@ -9584,7 +9585,7 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu) lnp_state_machine::check_line_address) will fail to properly exclude an entry that was removed via --gc-sections. */ if (lowpc != highpc) - handle_DW_AT_stmt_list (die, cu, lowpc); + handle_DW_AT_stmt_list (die, cu, fnd, lowpc); /* Process all dies in compilation unit. */ if (die->child != NULL) @@ -9658,7 +9659,7 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die) if (attr != NULL && attr->form_is_unsigned ()) { sect_offset line_offset = (sect_offset) attr->as_unsigned (); - lh = dwarf_decode_line_header (line_offset, this); + lh = dwarf_decode_line_header (line_offset, this, nullptr); } if (lh == NULL) { @@ -19739,7 +19740,8 @@ get_debug_line_section (struct dwarf2_cu *cu) and must not be freed. */ static line_header_up -dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu) +dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu, + const char *comp_dir) { struct dwarf2_section_info *section; dwarf2_per_objfile *per_objfile = cu->per_objfile; @@ -19756,7 +19758,8 @@ dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu) } return dwarf_decode_line_header (sect_off, cu->per_cu->is_dwz, - per_objfile, section, &cu->header); + per_objfile, section, &cu->header, + comp_dir); } /* Subroutine of dwarf_decode_lines to simplify it. -- 2.30.2