25
25
26
26
#include < linking/static_lifetime_init.h>
27
27
28
+ #include < goto-programs/goto_convert_functions.h>
28
29
#include < goto-programs/goto_model.h>
29
30
#include < goto-programs/read_goto_binary.h>
30
31
@@ -72,28 +73,33 @@ int linker_script_merget::add_linker_script_definitions()
72
73
return fail;
73
74
}
74
75
75
- fail=1 ;
76
76
linker_valuest linker_values;
77
- const auto &pair =
78
- original_goto_model->goto_functions .function_map .find (INITIALIZE_FUNCTION);
79
- if (pair == original_goto_model->goto_functions .function_map .end ())
80
- {
81
- log .error () << " No " << INITIALIZE_FUNCTION << " found in goto_functions"
82
- << messaget::eom;
83
- return fail;
84
- }
85
77
fail = ls_data2instructions (
86
78
data,
87
79
cmdline.get_value (' T' ),
88
- pair->second .body ,
89
80
original_goto_model->symbol_table ,
90
81
linker_values);
91
82
if (fail!=0 )
92
83
{
93
- log .error () << " Could not add linkerscript defs to " INITIALIZE_FUNCTION
84
+ log .error () << " Could not add linkerscript defs to symbol table "
94
85
<< messaget::eom;
95
86
return fail;
96
87
}
88
+ if (
89
+ original_goto_model->goto_functions .function_map .erase (
90
+ INITIALIZE_FUNCTION) != 0 )
91
+ {
92
+ static_lifetime_init (
93
+ original_goto_model->symbol_table ,
94
+ original_goto_model->symbol_table .lookup_ref (INITIALIZE_FUNCTION)
95
+ .location );
96
+ goto_convert (
97
+ INITIALIZE_FUNCTION,
98
+ original_goto_model->symbol_table ,
99
+ original_goto_model->goto_functions ,
100
+ log .get_message_handler ());
101
+ original_goto_model->goto_functions .update ();
102
+ }
97
103
98
104
fail=goto_and_object_mismatch (linker_defined_symbols, linker_values);
99
105
if (fail!=0 )
@@ -217,17 +223,6 @@ int linker_script_merget::pointerize_linker_defined_symbols(
217
223
const namespacet ns (goto_model.symbol_table );
218
224
219
225
int ret=0 ;
220
- // First, pointerize the actual linker-defined symbols
221
- for (const auto &pair : linker_values)
222
- {
223
- const auto maybe_symbol = goto_model.symbol_table .get_writeable (pair.first );
224
- if (!maybe_symbol)
225
- continue ;
226
- symbolt &entry=*maybe_symbol;
227
- entry.type =pointer_type (char_type ());
228
- entry.is_extern =false ;
229
- entry.value =pair.second .second ;
230
- }
231
226
232
227
// Next, find all occurrences of linker-defined symbols that are _values_
233
228
// of some symbol in the symbol table, and pointerize them too
@@ -421,12 +416,10 @@ the right behaviour for both implementations.
421
416
int linker_script_merget::ls_data2instructions (
422
417
jsont &data,
423
418
const std::string &linker_script,
424
- goto_programt &gp,
425
419
symbol_tablet &symbol_table,
426
420
linker_valuest &linker_values)
427
421
#if 1
428
422
{
429
- goto_programt::instructionst initialize_instructions=gp.instructions ;
430
423
std::map<irep_idt, std::size_t > truncated_symbols;
431
424
for (auto &d : to_json_array (data[" regions" ]))
432
425
{
@@ -453,24 +446,46 @@ int linker_script_merget::ls_data2instructions(
453
446
454
447
constant_exprt array_size_expr=from_integer (array_size, size_type ());
455
448
array_typet array_type (char_type (), array_size_expr);
456
- symbol_exprt array_expr (array_name.str (), array_type);
457
- source_locationt array_loc;
458
449
450
+ source_locationt array_loc;
459
451
array_loc.set_file (linker_script);
460
452
std::ostringstream array_comment;
461
453
array_comment << " Object section '" << d[" section" ].value << " ' of size "
462
454
<< array_size << " bytes" ;
463
455
array_loc.set_comment (array_comment.str ());
464
- array_expr.add_source_location ()=array_loc;
456
+
457
+ namespacet ns (symbol_table);
458
+ const auto zi = zero_initializer (array_type, array_loc, ns);
459
+ CHECK_RETURN (zi.has_value ());
460
+
461
+ // Add the array to the symbol table.
462
+ symbolt array_sym;
463
+ array_sym.is_static_lifetime = true ;
464
+ array_sym.is_lvalue = true ;
465
+ array_sym.is_state_var = true ;
466
+ array_sym.name = array_name.str ();
467
+ array_sym.type = array_type;
468
+ array_sym.value = *zi;
469
+ array_sym.location = array_loc;
470
+
471
+ bool failed = symbol_table.add (array_sym);
472
+ CHECK_RETURN (!failed);
465
473
466
474
// Array start address
467
- index_exprt zero_idx (array_expr , from_integer (0 , size_type ())) ;
475
+ index_exprt zero_idx{array_sym. symbol_expr () , from_integer (0 , size_type ())} ;
468
476
address_of_exprt array_start (zero_idx);
469
477
470
478
// Linker-defined symbol_exprt pointing to start address
471
- symbol_exprt start_sym (d[" start-symbol" ].value , pointer_type (char_type ()));
479
+ symbolt start_sym;
480
+ start_sym.is_static_lifetime = true ;
481
+ start_sym.is_lvalue = true ;
482
+ start_sym.is_state_var = true ;
483
+ start_sym.name = d[" start-symbol" ].value ;
484
+ start_sym.type = pointer_type (char_type ());
485
+ start_sym.value = array_start;
472
486
linker_values.emplace (
473
- d[" start-symbol" ].value , std::make_pair (start_sym, array_start));
487
+ d[" start-symbol" ].value ,
488
+ std::make_pair (start_sym.symbol_expr (), array_start));
474
489
475
490
// Since the value of the pointer will be a random CBMC address, write a
476
491
// note about the real address in the object file
@@ -494,22 +509,26 @@ int linker_script_merget::ls_data2instructions(
494
509
<< d[" section" ].value << " '. Original address in object file"
495
510
<< " is " << (*it)[" val" ].value ;
496
511
start_loc.set_comment (start_comment.str ());
497
- start_sym.add_source_location ()= start_loc;
512
+ start_sym.location = start_loc;
498
513
499
- // Instruction for start-address pointer in __CPROVER_initialize
500
- code_assignt start_assign (start_sym, array_start);
501
- start_assign.add_source_location ()=start_loc;
502
- goto_programt::instructiont start_assign_i =
503
- goto_programt::make_assignment (start_assign, start_loc);
504
- initialize_instructions.push_front (start_assign_i);
514
+ auto start_sym_entry = symbol_table.insert (start_sym);
515
+ if (!start_sym_entry.second )
516
+ start_sym_entry.first = start_sym;
505
517
506
518
if (has_end) // Same for pointer to end of array
507
519
{
508
520
plus_exprt array_end (array_start, array_size_expr);
509
521
510
- symbol_exprt end_sym (d[" end-symbol" ].value , pointer_type (char_type ()));
522
+ symbolt end_sym;
523
+ end_sym.is_static_lifetime = true ;
524
+ end_sym.is_lvalue = true ;
525
+ end_sym.is_state_var = true ;
526
+ end_sym.name = d[" end-symbol" ].value ;
527
+ end_sym.type = pointer_type (char_type ());
528
+ end_sym.value = array_end;
511
529
linker_values.emplace (
512
- d[" end-symbol" ].value , std::make_pair (end_sym, array_end));
530
+ d[" end-symbol" ].value ,
531
+ std::make_pair (end_sym.symbol_expr (), array_end));
513
532
514
533
auto entry = std::find_if (
515
534
to_json_array (data[" addresses" ]).begin (),
@@ -531,37 +550,12 @@ int linker_script_merget::ls_data2instructions(
531
550
<< " '. Original address in object file"
532
551
<< " is " << (*entry)[" val" ].value ;
533
552
end_loc.set_comment (end_comment.str ());
534
- end_sym.add_source_location ()= end_loc;
553
+ end_sym.location = end_loc;
535
554
536
- code_assignt end_assign (end_sym, array_end);
537
- end_assign.add_source_location ()=end_loc;
538
- goto_programt::instructiont end_assign_i =
539
- goto_programt::make_assignment (end_assign, end_loc);
540
- initialize_instructions.push_front (end_assign_i);
555
+ auto end_sym_entry = symbol_table.insert (end_sym);
556
+ if (!end_sym_entry.second )
557
+ end_sym_entry.first = end_sym;
541
558
}
542
-
543
- // Add the array to the symbol table. We don't add the pointer(s) to the
544
- // symbol table because they were already there, but declared as extern and
545
- // probably with a different type. We change the externness and type in
546
- // pointerize_linker_defined_symbols.
547
- symbolt array_sym;
548
- array_sym.name =array_name.str ();
549
- array_sym.pretty_name =array_name.str ();
550
- array_sym.is_lvalue =array_sym.is_static_lifetime =true ;
551
- array_sym.type =array_type;
552
- array_sym.location =array_loc;
553
- symbol_table.add (array_sym);
554
-
555
- // Push the array initialization to the front now, so that it happens before
556
- // the initialization of the symbols that point to it.
557
- namespacet ns (symbol_table);
558
- const auto zi = zero_initializer (array_type, array_loc, ns);
559
- CHECK_RETURN (zi.has_value ());
560
- code_assignt array_assign (array_expr, *zi);
561
- array_assign.add_source_location ()=array_loc;
562
- goto_programt::instructiont array_assign_i =
563
- goto_programt::make_assignment (array_assign, array_loc);
564
- initialize_instructions.push_front (array_assign_i);
565
559
}
566
560
567
561
// We've added every linker-defined symbol that marks the start or end of a
@@ -597,8 +591,6 @@ int linker_script_merget::ls_data2instructions(
597
591
loc.set_comment (" linker script-defined symbol: char *" +
598
592
d[" sym" ].value +" =" +" (char *)" +id2string (symbol_value)+" u;" );
599
593
600
- symbol_exprt lhs (d[" sym" ].value , pointer_type (char_type ()));
601
-
602
594
constant_exprt rhs (
603
595
integer2bvrep (
604
596
string2integer (id2string (symbol_value)),
@@ -607,14 +599,15 @@ int linker_script_merget::ls_data2instructions(
607
599
608
600
typecast_exprt rhs_tc (rhs, pointer_type (char_type ()));
609
601
610
- linker_values.emplace (
611
- irep_idt (d[" sym" ].value ), std::make_pair (lhs, rhs_tc));
602
+ symbolt &symbol = symbol_table.get_writeable_ref (d[" sym" ].value );
603
+ symbol.is_extern = false ;
604
+ symbol.is_static_lifetime = true ;
605
+ symbol.location = loc;
606
+ symbol.type = pointer_type (char_type ());
607
+ symbol.value = rhs_tc;
612
608
613
- code_assignt assign (lhs, rhs_tc);
614
- assign.add_source_location ()=loc;
615
- goto_programt::instructiont assign_i =
616
- goto_programt::make_assignment (assign, loc);
617
- initialize_instructions.push_front (assign_i);
609
+ linker_values.emplace (
610
+ irep_idt (d[" sym" ].value ), std::make_pair (symbol.symbol_expr (), rhs_tc));
618
611
}
619
612
return 0 ;
620
613
}
0 commit comments