@@ -13,7 +13,10 @@ Author: Malte Mues <mail.mues@gmail.com>
1313#include < util/c_types_util.h>
1414#include < util/config.h>
1515#include < util/expr_initializer.h>
16+ #include < util/pointer_offset_size.h>
17+ #include < util/string2int.h>
1618#include < util/string_constant.h>
19+ #include < util/string_utils.h>
1720
1821gdb_value_extractort::gdb_value_extractort (
1922 const symbol_tablet &symbol_table,
@@ -167,6 +170,89 @@ exprt gdb_value_extractort::get_char_pointer_value(
167170 }
168171}
169172
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+
170256exprt gdb_value_extractort::get_non_char_pointer_value (
171257 const exprt &expr,
172258 const memory_addresst &memory_location,
@@ -212,6 +298,24 @@ exprt gdb_value_extractort::get_non_char_pointer_value(
212298 }
213299}
214300
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+
215319exprt gdb_value_extractort::get_pointer_value (
216320 const exprt &expr,
217321 const exprt &zero_expr,
@@ -236,7 +340,9 @@ exprt gdb_value_extractort::get_pointer_value(
236340 else
237341 {
238342 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);
240346
241347 if (target_expr.id () == ID_nil)
242348 {
0 commit comments