From: Simon Marchi <simon.marchi@efficios.com>
To: gdb-patches@sourceware.org
Cc: Simon Marchi <simon.marchi@polymtl.ca>
Subject: [PATCH v3 1/7] gdb/dwarf: move dwo_unit and dwo_file to dwo.h
Date: Mon, 11 May 2026 11:40:27 -0400 [thread overview]
Message-ID: <20260511154053.142576-2-simon.marchi@efficios.com> (raw)
In-Reply-To: <20260511154053.142576-1-simon.marchi@efficios.com>
From: Simon Marchi <simon.marchi@polymtl.ca>
Move these types and some related things to a new dwo.h header file. My
goal is to allow index-write.c to see these types, in a later patch. I
initially moved them to read.h, but Tom suggested in review that read.h
was getting a bit too large.
Change-Id: Ia32e0643f95561d3a1bfb67d501c8e20f5682f0e
---
gdb/dwarf2/dwo.h | 219 ++++++++++++++++++++++++++++++++++++++++++++++
gdb/dwarf2/read.c | 170 +----------------------------------
gdb/dwarf2/read.h | 44 +---------
3 files changed, 221 insertions(+), 212 deletions(-)
create mode 100644 gdb/dwarf2/dwo.h
diff --git a/gdb/dwarf2/dwo.h b/gdb/dwarf2/dwo.h
new file mode 100644
index 000000000000..025932b1e969
--- /dev/null
+++ b/gdb/dwarf2/dwo.h
@@ -0,0 +1,219 @@
+/* DWARF 2 debugging format support for GDB.
+
+ Copyright (C) 1994-2026 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef GDB_DWARF2_DWO_H
+#define GDB_DWARF2_DWO_H
+
+#include "dwarf2/section.h"
+#include "gdb_bfd.h"
+#include "gdbsupport/unordered_set.h"
+#include "hashtab.h"
+
+/* These sections are what may appear in a (real or virtual) DWO file. */
+
+struct dwo_sections
+{
+ struct dwarf2_section_info abbrev;
+ struct dwarf2_section_info line;
+ struct dwarf2_section_info loc;
+ struct dwarf2_section_info loclists;
+ struct dwarf2_section_info macinfo;
+ struct dwarf2_section_info macro;
+ struct dwarf2_section_info rnglists;
+ struct dwarf2_section_info str;
+ struct dwarf2_section_info str_offsets;
+ /* In the case of a virtual DWO file, these two are unused. */
+ std::vector<dwarf2_section_info> infos;
+ std::vector<dwarf2_section_info> types;
+};
+
+/* CUs/TUs in DWP/DWO files. */
+
+struct dwo_unit
+{
+ /* Backlink to the containing struct dwo_file. */
+ struct dwo_file *dwo_file = nullptr;
+
+ /* The "id" that distinguishes this CU/TU.
+ .debug_info calls this "dwo_id", .debug_types calls this "signature".
+ Since signatures came first, we stick with it for consistency. */
+ ULONGEST signature = 0;
+
+ /* The section this CU/TU lives in, in the DWO file. */
+ dwarf2_section_info *section = nullptr;
+
+ /* This is set if SECTION is owned by this dwo_unit. */
+ dwarf2_section_info_up section_holder;
+
+ /* Same as dwarf2_per_cu::{sect_off,length} but in the DWO section. */
+ sect_offset sect_off {};
+ unsigned int length = 0;
+
+ /* For types, offset in the type's DIE of the type defined by this TU. */
+ cu_offset type_offset_in_tu;
+};
+
+using dwo_unit_up = std::unique_ptr<dwo_unit>;
+
+/* Hash function for dwo_unit objects, based on the signature. */
+
+struct dwo_unit_hash
+{
+ using is_transparent = void;
+
+ std::size_t operator() (ULONGEST signature) const noexcept
+ { return signature; }
+
+ std::size_t operator() (const dwo_unit_up &unit) const noexcept
+ { return (*this) (unit->signature); }
+};
+
+/* Equal function for dwo_unit objects, based on the signature.
+
+ The signature is assumed to be unique within the DWO file. So while object
+ file CU dwo_id's always have the value zero, that's OK, assuming each object
+ file DWO file has only one CU, and that's the rule for now. */
+
+struct dwo_unit_eq
+{
+ using is_transparent = void;
+
+ bool operator() (ULONGEST sig, const dwo_unit_up &unit) const noexcept
+ { return sig == unit->signature; }
+
+ bool operator() (const dwo_unit_up &a, const dwo_unit_up &b) const noexcept
+ { return (*this) (a->signature, b); }
+};
+
+/* Set of dwo_unit object, using their signature as identity. */
+
+using dwo_unit_set = gdb::unordered_set<dwo_unit_up, dwo_unit_hash, dwo_unit_eq>;
+
+/* Data for one DWO file.
+
+ This includes virtual DWO files (a virtual DWO file is a DWO file as it
+ appears in a DWP file). DWP files don't really have DWO files per se -
+ comdat folding of types "loses" the DWO file they came from, and from
+ a high level view DWP files appear to contain a mass of random types.
+ However, to maintain consistency with the non-DWP case we pretend DWP
+ files contain virtual DWO files, and we assign each TU with one virtual
+ DWO file (generally based on the line and abbrev section offsets -
+ a heuristic that seems to work in practice). */
+
+struct dwo_file
+{
+ dwo_file () = default;
+ DISABLE_COPY_AND_ASSIGN (dwo_file);
+
+ /* The DW_AT_GNU_dwo_name or DW_AT_dwo_name attribute.
+ For virtual DWO files the name is constructed from the section offsets
+ of abbrev,line,loc,str_offsets so that we combine virtual DWO files
+ from related CU+TUs. */
+ std::string dwo_name;
+
+ /* The DW_AT_comp_dir attribute. */
+ const char *comp_dir = nullptr;
+
+ /* The bfd, when the file is open. Otherwise this is NULL.
+ This is unused(NULL) for virtual DWO files where we use dwp_file.dbfd. */
+ gdb_bfd_ref_ptr dbfd;
+
+ /* The sections that make up this DWO file.
+ Remember that for virtual DWO files in DWP V2 or DWP V5, these are virtual
+ sections (for lack of a better name). */
+ struct dwo_sections sections {};
+
+ /* The CUs in the file.
+
+ Multiple CUs per DWO are supported as an extension to handle LLVM's Link
+ Time Optimization output (where multiple source files may be compiled into
+ a single object/dwo pair). */
+ dwo_unit_set cus;
+
+ /* Table of TUs in the file. */
+ dwo_unit_set tus;
+};
+
+using dwo_file_up = std::unique_ptr<dwo_file>;
+
+/* This is used when looking up entries in a dwo_file_set. */
+
+struct dwo_file_search
+{
+ /* Name of the DWO to look for. */
+ const char *dwo_name;
+
+ /* Compilation directory to look for. */
+ const char *comp_dir;
+};
+
+/* Hash function for dwo_file objects, using their dwo_name and comp_dir as
+ identity. */
+
+struct dwo_file_hash
+{
+ using is_transparent = void;
+
+ std::size_t operator() (const dwo_file_search &search) const noexcept
+ {
+ hashval_t hash = htab_hash_string (search.dwo_name);
+
+ if (search.comp_dir != nullptr)
+ hash += htab_hash_string (search.comp_dir);
+
+ return hash;
+ }
+
+ std::size_t operator() (const dwo_file_up &file) const noexcept
+ {
+ return (*this) ({ file->dwo_name.c_str (), file->comp_dir });
+ }
+};
+
+/* Equal function for dwo_file objects, using their dwo_name and comp_dir as
+ identity. */
+
+struct dwo_file_eq
+{
+ using is_transparent = void;
+
+ bool operator() (const dwo_file_search &search,
+ const dwo_file_up &dwo_file) const noexcept
+ {
+ if (search.dwo_name != dwo_file->dwo_name)
+ return false;
+
+ if (search.comp_dir == nullptr || dwo_file->comp_dir == nullptr)
+ return search.comp_dir == dwo_file->comp_dir;
+
+ return streq (search.comp_dir, dwo_file->comp_dir);
+ }
+
+ bool operator() (const dwo_file_up &a, const dwo_file_up &b) const noexcept
+ {
+ return (*this) ({ a->dwo_name.c_str (), a->comp_dir }, b);
+ }
+};
+
+/* Set of dwo_file objects, using their dwo_name and comp_dir as identity. */
+
+using dwo_file_up_set
+ = gdb::unordered_set<dwo_file_up, dwo_file_hash, dwo_file_eq>;
+
+#endif /* GDB_DWARF2_DWO_H */
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index efe96f6510da..46aa0201cc63 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -31,6 +31,7 @@
#include "dwarf2/abbrev.h"
#include "dwarf2/aranges.h"
#include "dwarf2/attribute.h"
+#include "dwarf2/dwo.h"
#include "dwarf2/unit-head.h"
#include "dwarf2/cooked-index-worker.h"
#include "dwarf2/cooked-indexer.h"
@@ -65,7 +66,6 @@
#include "dwarf2/expr.h"
#include "dwarf2/loc.h"
#include "cp-support.h"
-#include "hashtab.h"
#include "command.h"
#include "cli/cli-cmds.h"
#include "block.h"
@@ -266,86 +266,6 @@ struct loclists_rnglists_header
unsigned int offset_entry_count;
};
-/* These sections are what may appear in a (real or virtual) DWO file. */
-
-struct dwo_sections
-{
- struct dwarf2_section_info abbrev;
- struct dwarf2_section_info line;
- struct dwarf2_section_info loc;
- struct dwarf2_section_info loclists;
- struct dwarf2_section_info macinfo;
- struct dwarf2_section_info macro;
- struct dwarf2_section_info rnglists;
- struct dwarf2_section_info str;
- struct dwarf2_section_info str_offsets;
- /* In the case of a virtual DWO file, these two are unused. */
- std::vector<dwarf2_section_info> infos;
- std::vector<dwarf2_section_info> types;
-};
-
-/* CUs/TUs in DWP/DWO files. */
-
-struct dwo_unit
-{
- /* Backlink to the containing struct dwo_file. */
- struct dwo_file *dwo_file = nullptr;
-
- /* The "id" that distinguishes this CU/TU.
- .debug_info calls this "dwo_id", .debug_types calls this "signature".
- Since signatures came first, we stick with it for consistency. */
- ULONGEST signature = 0;
-
- /* The section this CU/TU lives in, in the DWO file. */
- dwarf2_section_info *section = nullptr;
-
- /* This is set if SECTION is owned by this dwo_unit. */
- dwarf2_section_info_up section_holder;
-
- /* Same as dwarf2_per_cu::{sect_off,length} but in the DWO section. */
- sect_offset sect_off {};
- unsigned int length = 0;
-
- /* For types, offset in the type's DIE of the type defined by this TU. */
- cu_offset type_offset_in_tu;
-};
-
-using dwo_unit_up = std::unique_ptr<dwo_unit>;
-
-/* Hash function for dwo_unit objects, based on the signature. */
-
-struct dwo_unit_hash
-{
- using is_transparent = void;
-
- std::size_t operator() (ULONGEST signature) const noexcept
- { return signature; }
-
- std::size_t operator() (const dwo_unit_up &unit) const noexcept
- { return (*this) (unit->signature); }
-};
-
-/* Equal function for dwo_unit objects, based on the signature.
-
- The signature is assumed to be unique within the DWO file. So while object
- file CU dwo_id's always have the value zero, that's OK, assuming each object
- file DWO file has only one CU, and that's the rule for now. */
-
-struct dwo_unit_eq
-{
- using is_transparent = void;
-
- bool operator() (ULONGEST sig, const dwo_unit_up &unit) const noexcept
- { return sig == unit->signature; }
-
- bool operator() (const dwo_unit_up &a, const dwo_unit_up &b) const noexcept
- { return (*this) (a->signature, b); }
-};
-
-/* Set of dwo_unit object, using their signature as identity. */
-
-using dwo_unit_set = gdb::unordered_set<dwo_unit_up, dwo_unit_hash, dwo_unit_eq>;
-
/* include/dwarf2.h defines the DWP section codes.
It defines a max value but it doesn't define a min value, which we
use for error checking, so provide one. */
@@ -355,94 +275,6 @@ enum dwp_v2_section_ids
DW_SECT_MIN = 1
};
-/* Data for one DWO file.
-
- This includes virtual DWO files (a virtual DWO file is a DWO file as it
- appears in a DWP file). DWP files don't really have DWO files per se -
- comdat folding of types "loses" the DWO file they came from, and from
- a high level view DWP files appear to contain a mass of random types.
- However, to maintain consistency with the non-DWP case we pretend DWP
- files contain virtual DWO files, and we assign each TU with one virtual
- DWO file (generally based on the line and abbrev section offsets -
- a heuristic that seems to work in practice). */
-
-struct dwo_file
-{
- dwo_file () = default;
- DISABLE_COPY_AND_ASSIGN (dwo_file);
-
- /* The DW_AT_GNU_dwo_name or DW_AT_dwo_name attribute.
- For virtual DWO files the name is constructed from the section offsets
- of abbrev,line,loc,str_offsets so that we combine virtual DWO files
- from related CU+TUs. */
- std::string dwo_name;
-
- /* The DW_AT_comp_dir attribute. */
- const char *comp_dir = nullptr;
-
- /* The bfd, when the file is open. Otherwise this is NULL.
- This is unused(NULL) for virtual DWO files where we use dwp_file.dbfd. */
- gdb_bfd_ref_ptr dbfd;
-
- /* The sections that make up this DWO file.
- Remember that for virtual DWO files in DWP V2 or DWP V5, these are virtual
- sections (for lack of a better name). */
- struct dwo_sections sections {};
-
- /* The CUs in the file.
-
- Multiple CUs per DWO are supported as an extension to handle LLVM's Link
- Time Optimization output (where multiple source files may be compiled into
- a single object/dwo pair). */
- dwo_unit_set cus;
-
- /* Table of TUs in the file. */
- dwo_unit_set tus;
-};
-
-/* See dwarf2/read.h. */
-
-std::size_t
-dwo_file_hash::operator() (const dwo_file_search &search) const noexcept
-{
- hashval_t hash = htab_hash_string (search.dwo_name);
-
- if (search.comp_dir != nullptr)
- hash += htab_hash_string (search.comp_dir);
-
- return hash;
-}
-
-/* See dwarf2/read.h. */
-
-std::size_t
-dwo_file_hash::operator() (const dwo_file_up &file) const noexcept
-{
- return (*this) ({ file->dwo_name.c_str (), file->comp_dir });
-}
-
-/* See dwarf2/read.h. */
-
-bool
-dwo_file_eq::operator() (const dwo_file_search &search,
- const dwo_file_up &dwo_file) const noexcept
-{
- if (search.dwo_name != dwo_file->dwo_name)
- return false;
-
- if (search.comp_dir == nullptr || dwo_file->comp_dir == nullptr)
- return search.comp_dir == dwo_file->comp_dir;
-
- return streq (search.comp_dir, dwo_file->comp_dir);
-}
-
-/* See dwarf2/read.h. */
-
-bool
-dwo_file_eq::operator() (const dwo_file_up &a,
- const dwo_file_up &b) const noexcept
-{ return (*this) ({ a->dwo_name.c_str (), a->comp_dir }, b); }
-
/* These sections are what may appear in a DWP file. */
struct dwp_sections
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index c65ee7f86990..63c3129ad9a8 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -22,6 +22,7 @@
#include <queue>
#include "dwarf2/abbrev.h"
+#include "dwarf2/dwo.h"
#include "dwarf2/unit-head.h"
#include "dwarf2/file-and-dir.h"
#include "dwarf2/index-cache.h"
@@ -529,49 +530,6 @@ using signatured_type_set
= gdb::unordered_set<signatured_type *, signatured_type_hash,
signatured_type_eq>;
-struct dwo_file;
-
-using dwo_file_up = std::unique_ptr<dwo_file>;
-
-/* This is used when looking up entries in a dwo_file_set. */
-
-struct dwo_file_search
-{
- /* Name of the DWO to look for. */
- const char *dwo_name;
-
- /* Compilation directory to look for. */
- const char *comp_dir;
-};
-
-/* Hash function for dwo_file objects, using their dwo_name and comp_dir as
- identity. */
-
-struct dwo_file_hash
-{
- using is_transparent = void;
-
- std::size_t operator() (const dwo_file_search &search) const noexcept;
- std::size_t operator() (const dwo_file_up &file) const noexcept;
-};
-
-/* Equal function for dwo_file objects, using their dwo_name and comp_dir as
- identity. */
-
-struct dwo_file_eq
-{
- using is_transparent = void;
-
- bool operator() (const dwo_file_search &search,
- const dwo_file_up &dwo_file) const noexcept;
- bool operator() (const dwo_file_up &a, const dwo_file_up &b) const noexcept;
-};
-
-/* Set of dwo_file objects, using their dwo_name and comp_dir as identity. */
-
-using dwo_file_up_set
- = gdb::unordered_set<dwo_file_up, dwo_file_hash, dwo_file_eq>;
-
struct dwp_file;
using dwp_file_up = std::unique_ptr<dwp_file>;
--
2.54.0
next prev parent reply other threads:[~2026-05-11 15:42 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-11 15:40 [PATCH v3 0/7] Handle foreign type units in .debug_names Simon Marchi
2026-05-11 15:40 ` Simon Marchi [this message]
2026-05-13 15:18 ` [PATCH v3 1/7] gdb/dwarf: move dwo_unit and dwo_file to dwo.h Tom Tromey
2026-05-13 17:30 ` Simon Marchi
2026-05-11 15:40 ` [PATCH v3 2/7] gdb/dwarf: move dwarf2_cu::section to cu.c Simon Marchi
2026-05-11 15:40 ` [PATCH v3 3/7] gdb/dwarf: add dwo_file::find_tus Simon Marchi
2026-05-11 15:40 ` [PATCH v3 4/7] gdb/dwarf: generate foreign type units in .debug_names Simon Marchi
2026-05-11 15:40 ` [PATCH v3 5/7] gdb/dwarf: add debug output in read-debug-names.c Simon Marchi
2026-05-11 15:40 ` [PATCH v3 6/7] gdb/dwarf: add more context to complaints in mapped_debug_names_reader::scan_one_entry Simon Marchi
2026-05-11 15:40 ` [PATCH v3 7/7] gdb/dwarf: read foreign type units Simon Marchi
2026-05-19 19:42 ` Guinevere Larsen
2026-05-19 20:10 ` Simon Marchi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260511154053.142576-2-simon.marchi@efficios.com \
--to=simon.marchi@efficios.com \
--cc=gdb-patches@sourceware.org \
--cc=simon.marchi@polymtl.ca \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox