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,43 @@ 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
+ std::string memory_location = pointer_value.address .string ();
181
+ PRECONDITION (memory_location != " 0x0" );
182
+ PRECONDITION (!pointer_value.pointee .empty ());
183
+
184
+ std::string struct_name;
185
+ size_t member_offset;
186
+ if (pointer_value.pointee .find (" +" ) != std::string::npos)
187
+ {
188
+ std::string member_offset_string;
189
+ split_string (
190
+ pointer_value.pointee , ' +' , struct_name, member_offset_string, true );
191
+ member_offset = safe_string2size_t (member_offset_string);
192
+ }
193
+ else
194
+ {
195
+ struct_name = pointer_value.pointee ;
196
+ member_offset = 0 ;
197
+ }
198
+
199
+ const symbolt *struct_symbol = symbol_table.lookup (struct_name);
200
+ DATA_INVARIANT (struct_symbol != nullptr , " unknown struct" );
201
+
202
+ const auto maybe_member_expr = get_subexpression_at_offset (
203
+ struct_symbol->symbol_expr (), member_offset, expr.type ().subtype (), ns);
204
+ if (maybe_member_expr.has_value ())
205
+ return *maybe_member_expr;
206
+
207
+ UNREACHABLE;
208
+ }
209
+
170
210
exprt gdb_value_extractort::get_non_char_pointer_value (
171
211
const exprt &expr,
172
212
const memory_addresst &memory_location,
@@ -212,6 +252,24 @@ exprt gdb_value_extractort::get_non_char_pointer_value(
212
252
}
213
253
}
214
254
255
+ bool gdb_value_extractort::points_to_member (
256
+ const pointer_valuet &pointer_value) const
257
+ {
258
+ if (pointer_value.pointee .find (" +" ) != std::string::npos)
259
+ return true ;
260
+
261
+ const symbolt *pointee_symbol = symbol_table.lookup (pointer_value.pointee );
262
+ if (pointee_symbol == nullptr )
263
+ return false ;
264
+ const auto pointee_type = pointee_symbol->type ;
265
+ if (
266
+ pointee_type.id () == ID_struct_tag || pointee_type.id () == ID_union_tag ||
267
+ pointee_type.id () == ID_array || pointee_type.id () == ID_struct ||
268
+ pointee_type.id () == ID_union)
269
+ return true ;
270
+ return false ;
271
+ }
272
+
215
273
exprt gdb_value_extractort::get_pointer_value (
216
274
const exprt &expr,
217
275
const exprt &zero_expr,
@@ -236,7 +294,9 @@ exprt gdb_value_extractort::get_pointer_value(
236
294
else
237
295
{
238
296
const exprt target_expr =
239
- get_non_char_pointer_value (expr, memory_location, location);
297
+ points_to_member (value)
298
+ ? get_pointer_to_member_value (expr, value, location)
299
+ : get_non_char_pointer_value (expr, memory_location, location);
240
300
241
301
if (target_expr.id () == ID_nil)
242
302
{
0 commit comments