GNU Binutils with patches for OS216
Revisión | 90c3c3ef0b5d0861a2f16137c55c9791e21714fc (tree) |
---|---|
Tiempo | 2019-11-21 14:27:37 |
Autor | Simon Marchi <simon.marchi@poly...> |
Commiter | Simon Marchi |
Hi Andrew
Change-Id: I695d9860d6f7dae86f966dfc0524b934660478da
@@ -69,14 +69,14 @@ mi_cmd_symbol_list_lines (const char *command, char **argv, int argc) | ||
69 | 69 | results. */ |
70 | 70 | |
71 | 71 | static void |
72 | -mi_info_one_symbol_details (enum search_domain kind, | |
73 | - struct symbol *sym, int block) | |
72 | +output_debug_symbol (ui_out *uiout, enum search_domain kind, | |
73 | + struct symbol *sym, int block) | |
74 | 74 | { |
75 | - struct ui_out *uiout = current_uiout; | |
76 | - | |
77 | 75 | ui_out_emit_tuple tuple_emitter (uiout, NULL); |
76 | + | |
78 | 77 | if (SYMBOL_LINE (sym) != 0) |
79 | 78 | uiout->field_unsigned ("line", SYMBOL_LINE (sym)); |
79 | + | |
80 | 80 | uiout->field_string ("name", SYMBOL_PRINT_NAME (sym)); |
81 | 81 | |
82 | 82 | if (kind == FUNCTIONS_DOMAIN || kind == VARIABLES_DOMAIN) |
@@ -90,153 +90,18 @@ mi_info_one_symbol_details (enum search_domain kind, | ||
90 | 90 | } |
91 | 91 | } |
92 | 92 | |
93 | -/* This class is used to produce the nested structure of tuples and lists | |
94 | - required to present the results of the MI_SYMBOL_INFO function. */ | |
95 | -class mi_symbol_info_emitter | |
93 | +/* Actually output one nondebug symbol, puts a tuple emitter in place | |
94 | + and then outputs the fields for this msymbol. */ | |
95 | +static void | |
96 | +output_nondebug_symbol (ui_out *uiout, | |
97 | + const struct bound_minimal_symbol &msymbol) | |
96 | 98 | { |
97 | - /* When printing debug symbols we need to track the last symtab so we can | |
98 | - spot when we have entered a new one. */ | |
99 | - const symtab *m_last_symtab; | |
100 | - | |
101 | - /* The ui_out to which output will be sent. */ | |
102 | - struct ui_out *m_uiout; | |
103 | - | |
104 | - /* The outer container for all the matched symbols. */ | |
105 | - ui_out_emit_tuple m_outer_symbols; | |
106 | - | |
107 | - /* The order of these optional emitters is critical as they will be | |
108 | - deleted in reverse order, which is important as these are popped from | |
109 | - the uiout stack as they are destroyed. */ | |
110 | - gdb::optional<ui_out_emit_list> m_debug_emitter; | |
111 | - gdb::optional<ui_out_emit_tuple> m_symtab_emitter; | |
112 | - gdb::optional<ui_out_emit_list> m_symbols_emitter; | |
113 | - gdb::optional<ui_out_emit_list> m_nondebug_emitter; | |
114 | - | |
115 | - /* Called when we might want to print our first nondebug symbol in order | |
116 | - to shutdown any debug symbol printing that might be in progress. */ | |
117 | - void maybe_finish_debug_output () | |
118 | - { | |
119 | - /* If the debug emitter is in use. */ | |
120 | - if (m_debug_emitter.has_value ()) | |
121 | - { | |
122 | - /* Then we should have a symbols list inside a symtab tuple also | |
123 | - currently in use. */ | |
124 | - gdb_assert (m_symbols_emitter.has_value ()); | |
125 | - gdb_assert (m_symtab_emitter.has_value ()); | |
126 | - | |
127 | - /* Shut down the symbols list, symtab tuple, and debug list | |
128 | - emitters (in that order). We are now back to the level of the | |
129 | - outer_symbols tuple ready to (possibly) start a nondebug list, | |
130 | - though that is not done here. */ | |
131 | - m_symbols_emitter.reset (); | |
132 | - m_symtab_emitter.reset (); | |
133 | - m_debug_emitter.reset (); | |
134 | - } | |
135 | - } | |
136 | - | |
137 | - /* Return true if the nondebug emitter has been put in place. */ | |
138 | - bool have_started_nondebug_symbol_output () const | |
139 | - { | |
140 | - return m_nondebug_emitter.has_value (); | |
141 | - } | |
142 | - | |
143 | - /* Called before we print every nondebug symbol. If this is the first | |
144 | - nondebug symbol to be printed then it will setup the emitters required | |
145 | - to print nondebug symbols. */ | |
146 | - void maybe_start_nondebug_symbol_output () | |
147 | - { | |
148 | - if (!have_started_nondebug_symbol_output ()) | |
149 | - m_nondebug_emitter.emplace (m_uiout, "nondebug"); | |
150 | - } | |
99 | + struct gdbarch *gdbarch = get_objfile_arch (msymbol.objfile); | |
100 | + ui_out_emit_tuple tuple_emitter (uiout, NULL); | |
151 | 101 | |
152 | - /* Actually output one nondebug symbol, puts a tuple emitter in place | |
153 | - and then outputs the fields for this msymbol. */ | |
154 | - void output_nondebug_symbol (const struct bound_minimal_symbol &msymbol) | |
155 | - { | |
156 | - struct gdbarch *gdbarch = get_objfile_arch (msymbol.objfile); | |
157 | - ui_out_emit_tuple tuple_emitter (m_uiout, NULL); | |
158 | - m_uiout->field_core_addr ("address", gdbarch, | |
159 | - BMSYMBOL_VALUE_ADDRESS (msymbol)); | |
160 | - m_uiout->field_string ("name", MSYMBOL_PRINT_NAME (msymbol.minsym)); | |
161 | - } | |
162 | - | |
163 | - /* Called before we print every debug symbol. If this is the first debug | |
164 | - symbol to be printed then it will setup the top level of emitters | |
165 | - required to print debug symbols. */ | |
166 | - void maybe_start_debug_symbol_output () | |
167 | - { | |
168 | - if (!m_debug_emitter.has_value ()) | |
169 | - m_debug_emitter.emplace (m_uiout, "debug"); | |
170 | - } | |
171 | - | |
172 | - /* Called before we print every debug symbol, S is the symtab for the | |
173 | - symbol to be printed. If S is different to the last symtab we printed | |
174 | - for then we close down the emitters for the last symtab, and create | |
175 | - new emitters for this new symtab. */ | |
176 | - void setup_emitters_for_symtab (symtab *s) | |
177 | - { | |
178 | - if (s != m_last_symtab) | |
179 | - { | |
180 | - /* Reset a possible previous symbol list within a symtab. */ | |
181 | - m_symbols_emitter.reset (); | |
182 | - m_symtab_emitter.reset (); | |
183 | - | |
184 | - /* Start a new symtab and symbol list within the symtab. */ | |
185 | - m_symtab_emitter.emplace (m_uiout, nullptr); | |
186 | - m_uiout->field_string ("filename", | |
187 | - symtab_to_filename_for_display (s)); | |
188 | - m_uiout->field_string ("fullname", symtab_to_fullname (s)); | |
189 | - m_symbols_emitter.emplace (m_uiout, "symbols"); | |
190 | - | |
191 | - /* Record the current symtab. */ | |
192 | - m_last_symtab = s; | |
193 | - } | |
194 | - } | |
195 | - | |
196 | -public: | |
197 | - /* Constructor. */ | |
198 | - mi_symbol_info_emitter (struct ui_out *uiout) | |
199 | - : m_last_symtab (nullptr), | |
200 | - m_uiout (uiout), | |
201 | - m_outer_symbols (uiout, "symbols") | |
202 | - { /* Nothing. */ } | |
203 | - | |
204 | - /* Output P a symbol found by searching for symbols of type KIND. */ | |
205 | - void output (const symbol_search &p, enum search_domain kind) | |
206 | - { | |
207 | - if (p.msymbol.minsym != NULL) | |
208 | - { | |
209 | - /* If this is the first nondebug symbol, and we have previous | |
210 | - outputted a debug symbol then we need to close down all of the | |
211 | - emitters related to printing debug symbols. */ | |
212 | - maybe_finish_debug_output (); | |
213 | - | |
214 | - /* If this is the first nondebug symbol then we need to create the | |
215 | - emitters related to printing nondebug symbols. */ | |
216 | - maybe_start_nondebug_symbol_output (); | |
217 | - | |
218 | - /* We are no safe to emit the nondebug symbol. */ | |
219 | - output_nondebug_symbol (p.msymbol); | |
220 | - } | |
221 | - else | |
222 | - { | |
223 | - /* All debug symbols should appear in the list before all | |
224 | - non-debug symbols. */ | |
225 | - gdb_assert (!have_started_nondebug_symbol_output ()); | |
226 | - | |
227 | - /* If this is the first debug symbol then we need to create the | |
228 | - outer level of emitters related to printing debug symbols. */ | |
229 | - maybe_start_debug_symbol_output (); | |
230 | - | |
231 | - /* Ensure the correct emitters are in place to emit this debug | |
232 | - symbol. */ | |
233 | - setup_emitters_for_symtab (symbol_symtab (p.symbol)); | |
234 | - | |
235 | - /* Emit information for this debug symbol. */ | |
236 | - mi_info_one_symbol_details (kind, p.symbol, p.block); | |
237 | - } | |
238 | - } | |
239 | -}; | |
102 | + uiout->field_core_addr ("address", gdbarch, BMSYMBOL_VALUE_ADDRESS (msymbol)); | |
103 | + uiout->field_string ("name", MSYMBOL_PRINT_NAME (msymbol.minsym)); | |
104 | +} | |
240 | 105 | |
241 | 106 | /* This is the guts of the commands '-symbol-info-functions', |
242 | 107 | '-symbol-info-variables', and '-symbol-info-types'. It calls |
@@ -253,12 +118,55 @@ mi_symbol_info (enum search_domain kind, const char *regexp, | ||
253 | 118 | /* Must make sure that if we're interrupted, symbols gets freed. */ |
254 | 119 | global_symbol_searcher sym_search (kind, regexp, t_regexp, exclude_minsyms); |
255 | 120 | std::vector<symbol_search> symbols = sym_search.search (); |
121 | + ui_out *uiout = current_uiout; | |
122 | + int i = 0; | |
123 | + | |
124 | + ui_out_emit_tuple outer_symbols_emitter (uiout, "symbols"); | |
256 | 125 | |
257 | - mi_symbol_info_emitter emitter (current_uiout); | |
258 | - for (const symbol_search &p : symbols) | |
126 | + /* Debug symbols are placed first. */ | |
127 | + if (i < symbols.size () && symbols[i].msymbol.minsym == nullptr) | |
259 | 128 | { |
260 | - QUIT; | |
261 | - emitter.output (p, kind); | |
129 | + ui_out_emit_list debug_symbols_list_emitter (uiout, "debug"); | |
130 | + | |
131 | + /* As long as we have debug symbols... */ | |
132 | + while (i < symbols.size () && symbols[i].msymbol.minsym == nullptr) | |
133 | + { | |
134 | + symtab *symtab = symbol_symtab (symbols[i].symbol); | |
135 | + ui_out_emit_tuple symtab_tuple_emitter (uiout, nullptr); | |
136 | + | |
137 | + uiout->field_string ("filename", symtab_to_filename_for_display (symtab)); | |
138 | + uiout->field_string ("fullname", symtab_to_fullname (symtab)); | |
139 | + | |
140 | + ui_out_emit_list symbols_list_emitter (uiout, "symbols"); | |
141 | + | |
142 | + /* As long as we have debug symbols from this symtab... */ | |
143 | + while (i < symbols.size () | |
144 | + && symbols[i].msymbol.minsym == nullptr | |
145 | + && symbol_symtab (symbols[i].symbol) == symtab) | |
146 | + { | |
147 | + symbol_search &s = symbols[i]; | |
148 | + | |
149 | + output_debug_symbol(uiout, kind, s.symbol, s.block); | |
150 | + | |
151 | + i++; | |
152 | + } | |
153 | + } | |
154 | + } | |
155 | + | |
156 | + /* Non-debug symbols are placed after. */ | |
157 | + if (i < symbols.size ()) | |
158 | + { | |
159 | + ui_out_emit_list nondebug_symbols_list_emitter (uiout, "nondebug"); | |
160 | + | |
161 | + /* As long as we have nondebug symbols... */ | |
162 | + while (i < symbols.size ()) | |
163 | + { | |
164 | + gdb_assert (symbols[i].msymbol.minsym != nullptr); | |
165 | + | |
166 | + output_nondebug_symbol(uiout, symbols[i].msymbol); | |
167 | + | |
168 | + i++; | |
169 | + } | |
262 | 170 | } |
263 | 171 | } |
264 | 172 |