13
13
#include < util/c_types_util.h>
14
14
#include < util/config.h>
15
15
#include < util/expr_initializer.h>
16
+ #include < util/pointer_offset_size.h>
17
+ #include < util/string2int.h>
16
18
#include < util/string_constant.h>
19
+ #include < util/string_utils.h>
17
20
18
21
gdb_value_extractort::gdb_value_extractort (
19
22
const symbol_tablet &symbol_table,
@@ -167,6 +170,89 @@ exprt gdb_value_extractort::get_char_pointer_value(
167
170
}
168
171
}
169
172
173
+ exprt gdb_value_extractort::get_pointer_to_member_value (
174
+ const exprt &expr,
175
+ const pointer_valuet &pointer_value,
176
+ const source_locationt &location)
177
+ {
178
+ PRECONDITION (expr.type ().id () == ID_pointer);
179
+ PRECONDITION (!is_c_char_type (expr.type ().subtype ()));
180
+ const auto &memory_location = pointer_value.address ;
181
+ std::string memory_location_string = memory_location.string ();
182
+ PRECONDITION (memory_location_string != " 0x0" );
183
+ PRECONDITION (!pointer_value.pointee .empty ());
184
+
185
+ std::string struct_name;
186
+ size_t member_offset;
187
+ if (pointer_value.pointee .find (" +" ) != std::string::npos)
188
+ {
189
+ std::string member_offset_string;
190
+ split_string (
191
+ pointer_value.pointee , ' +' , struct_name, member_offset_string, true );
192
+ member_offset = safe_string2size_t (member_offset_string);
193
+ }
194
+ else
195
+ {
196
+ struct_name = pointer_value.pointee ;
197
+ member_offset = 0 ;
198
+ }
199
+
200
+ const symbolt *struct_symbol = symbol_table.lookup (struct_name);
201
+ DATA_INVARIANT (struct_symbol != nullptr , " unknown struct" );
202
+ const auto maybe_struct_size =
203
+ pointer_offset_size (struct_symbol->symbol_expr ().type (), ns);
204
+ bool found = false ;
205
+ CHECK_RETURN (maybe_struct_size.has_value ());
206
+ for (const auto &value_pair : values)
207
+ {
208
+ const auto &value_symbol_expr = value_pair.second ;
209
+ if (
210
+ struct_name ==
211
+ id2string (to_symbol_expr (value_symbol_expr).get_identifier ()))
212
+ {
213
+ found = true ;
214
+ break ;
215
+ }
216
+ }
217
+
218
+ if (!found)
219
+ {
220
+ const typet target_type = expr.type ().subtype ();
221
+
222
+ symbol_exprt dummy (expr.type ());
223
+ code_blockt assignments;
224
+
225
+ const symbol_exprt new_symbol =
226
+ to_symbol_expr (allocate_objects.allocate_automatic_local_object (
227
+ assignments, dummy, target_type));
228
+
229
+ dereference_exprt dereference_expr (expr);
230
+
231
+ const auto zero_expr = zero_initializer (target_type, location, ns);
232
+ CHECK_RETURN (zero_expr);
233
+
234
+ // add assignment of value to newly created symbol
235
+ add_assignment (new_symbol, *zero_expr);
236
+
237
+ values[memory_location] = new_symbol;
238
+
239
+ const auto &struct_symbol = values.find (memory_location);
240
+
241
+ const auto maybe_member_expr = get_subexpression_at_offset (
242
+ struct_symbol->second , member_offset, expr.type ().subtype (), ns);
243
+ if (maybe_member_expr.has_value ())
244
+ return *maybe_member_expr;
245
+ UNREACHABLE;
246
+ }
247
+
248
+ const auto maybe_member_expr = get_subexpression_at_offset (
249
+ struct_symbol->symbol_expr (), member_offset, expr.type ().subtype (), ns);
250
+ if (maybe_member_expr.has_value ())
251
+ return *maybe_member_expr;
252
+
253
+ UNREACHABLE;
254
+ }
255
+
170
256
exprt gdb_value_extractort::get_non_char_pointer_value (
171
257
const exprt &expr,
172
258
const memory_addresst &memory_location,
@@ -212,6 +298,24 @@ exprt gdb_value_extractort::get_non_char_pointer_value(
212
298
}
213
299
}
214
300
301
+ bool gdb_value_extractort::points_to_member (
302
+ const pointer_valuet &pointer_value) const
303
+ {
304
+ if (pointer_value.pointee .find (" +" ) != std::string::npos)
305
+ return true ;
306
+
307
+ const symbolt *pointee_symbol = symbol_table.lookup (pointer_value.pointee );
308
+ if (pointee_symbol == nullptr )
309
+ return false ;
310
+ const auto pointee_type = pointee_symbol->type ;
311
+ if (
312
+ pointee_type.id () == ID_struct_tag || pointee_type.id () == ID_union_tag ||
313
+ pointee_type.id () == ID_array || pointee_type.id () == ID_struct ||
314
+ pointee_type.id () == ID_union)
315
+ return true ;
316
+ return false ;
317
+ }
318
+
215
319
exprt gdb_value_extractort::get_pointer_value (
216
320
const exprt &expr,
217
321
const exprt &zero_expr,
@@ -236,7 +340,9 @@ exprt gdb_value_extractort::get_pointer_value(
236
340
else
237
341
{
238
342
const exprt target_expr =
239
- get_non_char_pointer_value (expr, memory_location, location);
343
+ points_to_member (value)
344
+ ? get_pointer_to_member_value (expr, value, location)
345
+ : get_non_char_pointer_value (expr, memory_location, location);
240
346
241
347
if (target_expr.id () == ID_nil)
242
348
{
0 commit comments