1212#ifndef DRGN_DWARF_INDEX_H
1313#define DRGN_DWARF_INDEX_H
1414
15- #include <elfutils/libdw .h>
15+ #include <elfutils/libdwfl .h>
1616#include <libelf.h>
1717#include <omp.h>
1818#include <stddef.h>
1919#include <stdint.h>
2020
2121#include "drgn.h"
2222#include "hash_table.h"
23+ #include "string_builder.h"
2324#include "vector.h"
2425
2526/**
4445 * @{
4546 */
4647
47- enum {
48- SECTION_SYMTAB ,
49- SECTION_DEBUG_ABBREV ,
50- SECTION_DEBUG_INFO ,
51- SECTION_DEBUG_LINE ,
52- SECTION_DEBUG_STR ,
53- DRGN_DWARF_INDEX_NUM_SECTIONS ,
54- };
55-
56- struct drgn_dwarf_index_file {
57- Elf_Data * sections [DRGN_DWARF_INDEX_NUM_SECTIONS ];
58- bool failed ;
48+ /**
49+ * drgn-specific data for the @c Dwfl_Module userdata pointer.
50+ *
51+ * For a newly created userdata, @c indexed is @c false and @c err is @c NULL.
52+ * They are updated by @ref drgn_dwarf_index_update(). @c err may be set with
53+ * @ref drgn_dwfl_module_userdata_set_error() before @ref
54+ * drgn_dwarf_index_update() is called to skip indexing for that module; the
55+ * error message will be added to the @ref DRGN_ERROR_MISSING_DEBUG_INFO error.
56+ *
57+ * @sa drgn_dwfl_find_elf(), drgn_dwfl_section_address()
58+ */
59+ struct drgn_dwfl_module_userdata {
60+ /** Whether the module is indexed in a @ref drgn_dwarf_index. */
61+ bool indexed ;
62+ /** File descriptor of @ref drgn_dwfl_module_userdata::elf. */
5963 int fd ;
60- /*
61- * If this is NULL, then we didn't open the file and don't own the Elf
62- * handle.
63- */
64- const char * path ;
64+ /** Error encountered while indexing. */
65+ struct drgn_error * err ;
66+ /** Path of @ref drgn_dwfl_module_userdata::elf. */
67+ char * path ;
68+ /** ELF handle to use. */
6569 Elf * elf ;
66- Dwarf * dwarf ;
67- Elf_Data * rela_sections [DRGN_DWARF_INDEX_NUM_SECTIONS ];
68- struct drgn_dwarf_index_file * next ;
6970};
7071
71- static inline const char *
72- drgn_dwarf_index_file_to_key (struct drgn_dwarf_index_file * const * entry )
72+ struct drgn_dwfl_module_userdata * drgn_dwfl_module_userdata_create (void );
73+
74+ void
75+ drgn_dwfl_module_userdata_destroy (struct drgn_dwfl_module_userdata * userdata );
76+
77+ /* This takes ownership of err. */
78+ void
79+ drgn_dwfl_module_userdata_set_error (struct drgn_dwfl_module_userdata * userdata ,
80+ const char * message ,
81+ struct drgn_error * err );
82+
83+ extern const Dwfl_Callbacks drgn_dwfl_callbacks ;
84+
85+ /** Get the @ref drgn_dwfl_module_userdata for a @c Dwfl_Module. */
86+ static inline struct drgn_dwfl_module_userdata *
87+ drgn_dwfl_module_userdata (Dwfl_Module * module )
7388{
74- return (* entry )-> path ;
89+ void * * userdatap ;
90+
91+ dwfl_module_info (module , & userdatap , NULL , NULL , NULL , NULL , NULL ,
92+ NULL );
93+ return * userdatap ;
7594}
76- DEFINE_HASH_TABLE_TYPE (drgn_dwarf_index_file_table ,
77- struct drgn_dwarf_index_file * ,
78- drgn_dwarf_index_file_to_key )
7995
8096struct drgn_dwarf_index_die ;
8197DEFINE_HASH_MAP_TYPE (drgn_dwarf_index_die_map , struct string , size_t )
@@ -102,23 +118,14 @@ struct drgn_dwarf_index_shard {
102118 * files. It is much faster for this task than other generic DWARF parsing
103119 * libraries.
104120 *
105- * A new DWARF index is created by @ref drgn_dwarf_index_create(). It is freed
106- * by @ref drgn_dwarf_index_destroy().
107- *
108- * Indexing happens in two steps: the files to index are opened using @ref
109- * drgn_dwarf_index_open(), then they all are parsed and indexed by @ref
110- * drgn_dwarf_index_update(). The update step is parallelized across CPUs, so it
111- * is most efficient to open as many files as possible before indexing them all
112- * at once in parallel.
113- *
114121 * Searches in the index are done with a @ref drgn_dwarf_index_iterator.
115122 */
116123struct drgn_dwarf_index {
117- /** @privatesection */
118- struct drgn_dwarf_index_file_table files ;
119- struct drgn_dwarf_index_file * opened_first , * opened_last ;
120- struct drgn_dwarf_index_file * indexed_first , * indexed_last ;
121- /* The index is sharded to reduce lock contention. */
124+ /**
125+ * Index shards.
126+ *
127+ * This is sharded to reduce lock contention.
128+ */
122129 struct drgn_dwarf_index_shard shards [1 << DRGN_DWARF_INDEX_SHARD_BITS ];
123130};
124131
@@ -134,44 +141,36 @@ void drgn_dwarf_index_init(struct drgn_dwarf_index *dindex);
134141void drgn_dwarf_index_deinit (struct drgn_dwarf_index * dindex );
135142
136143/**
137- * Open a file and add it to a DWARF index .
144+ * Index new DWARF information .
138145 *
139- * This function does the first part of indexing a file: it opens the file,
140- * reads or maps it, and checks that it contains the required debugging
141- * information. However, it does not actually parse the debugging information.
142- * To do so, call drgn_dwarf_index_update() once all of the files to index have
143- * been opened.
146+ * This parses and indexes the debugging information for all modules in @p dwfl
147+ * that have not yet been indexed.
144148 *
145- * If this fails, the file is not opened, but previously opened files are not
146- * affected.
149+ * On success, @ref drgn_dwfl_module_userdata::indexed is set to @c true for all
150+ * modules that we were able to index, and @ref drgn_dwfl_module_userdata::err
151+ * is set to non-@c NULL for all other modules.
152+ *
153+ * If debug information was not available for one or more modules, a @ref
154+ * DRGN_ERROR_MISSING_DEBUG_INFO error is returned.
155+ *
156+ * On any other error, no new debugging information is indexed.
147157 *
148- * @param[in] dindex DWARF index.
149- * @param[in] path Path to open.
150- * @param[out] elf If not @c NULL, the opened ELF file. It is valid until @ref
151- * drgn_dwarf_index_destroy() is called.
152158 * @return @c NULL on success, non-@c NULL on error.
153159 */
154- struct drgn_error * drgn_dwarf_index_open (struct drgn_dwarf_index * dindex ,
155- const char * path , Elf * * elf );
156-
157- /** Close any files which haven't been indexed yet. */
158- void drgn_dwarf_index_close_unindexed (struct drgn_dwarf_index * dindex );
160+ struct drgn_error * drgn_dwarf_index_update (struct drgn_dwarf_index * dindex ,
161+ Dwfl * dwfl );
159162
160163/**
161- * Index newly opened files.
162- *
163- * This function does the second part of indexing a file: it applies ELF
164- * relocations, then parses and indexes the debugging information in all of the
165- * files opened by @ref drgn_dwarf_index_open() since the last call to @ref
166- * drgn_dwarf_index_update() or @ref drgn_dwarf_index_create().
167- *
168- * If this fails, no new debugging information is indexed and all opened files
169- * which were not already indexed are closed.
164+ * Remove all @c Dwfl_Modules that aren't indexed (see @ref
165+ * drgn_dwfl_module_userdata::indexed) from @p dwfl.
170166 *
171- * @param[in] dindex DWARF index.
172- * @return @c NULL on success, non-@c NULL on error .
167+ * This should be called if @ref drgn_dwarf_index_update() returned an error or
168+ * if modules were reported and @ref drgn_dwarf_index_update() was not called .
173169 */
174- struct drgn_error * drgn_dwarf_index_update (struct drgn_dwarf_index * dindex );
170+ void drgn_remove_unindexed_dwfl_modules (Dwfl * dwfl );
171+
172+ /** Remove all @Dwfl_Modules from @p dwfl. */
173+ void drgn_remove_all_dwfl_modules (Dwfl * dwfl );
175174
176175/**
177176 * Iterator over DWARF debugging information.
@@ -215,14 +214,17 @@ void drgn_dwarf_index_iterator_init(struct drgn_dwarf_index_iterator *it,
215214 *
216215 * @param[in] it DWARF index iterator.
217216 * @param[out] die_ret Returned DIE.
217+ * @param[out] bias_ret Returned difference between addresses in the loaded
218+ * module and addresses in the debugging information. This may be @c NULL if it
219+ * is not needed.
218220 * @return @c NULL on success, non-@c NULL on error. In particular, when there
219221 * are no more matching DIEs, @p die_ret is not modified and an error with code
220222 * @ref DRGN_ERROR_STOP is returned; this @ref DRGN_ERROR_STOP error does not
221223 * have to be passed to @ref drgn_error_destroy().
222224 */
223225struct drgn_error *
224226drgn_dwarf_index_iterator_next (struct drgn_dwarf_index_iterator * it ,
225- Dwarf_Die * die_ret );
227+ Dwarf_Die * die_ret , uint64_t * bias_ret );
226228
227229/** @} */
228230
0 commit comments