@@ -25,6 +25,7 @@ Author: Kareem Khazem <karkhaz@karkhaz.com>, 2017
2525
2626#include < linking/static_lifetime_init.h>
2727
28+ #include < goto-programs/goto_convert_functions.h>
2829#include < goto-programs/goto_model.h>
2930#include < goto-programs/read_goto_binary.h>
3031
@@ -72,28 +73,33 @@ int linker_script_merget::add_linker_script_definitions()
7273 return fail;
7374 }
7475
75- fail=1 ;
7676 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- }
8577 fail = ls_data2instructions (
8678 data,
8779 cmdline.get_value (' T' ),
88- pair->second .body ,
8980 original_goto_model->symbol_table ,
9081 linker_values);
9182 if (fail!=0 )
9283 {
93- log.error () << " Could not add linkerscript defs to " INITIALIZE_FUNCTION
84+ log.error () << " Could not add linkerscript defs to symbol table "
9485 << messaget::eom;
9586 return fail;
9687 }
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+ }
97103
98104 fail=goto_and_object_mismatch (linker_defined_symbols, linker_values);
99105 if (fail!=0 )
@@ -217,17 +223,6 @@ int linker_script_merget::pointerize_linker_defined_symbols(
217223 const namespacet ns (goto_model.symbol_table );
218224
219225 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- }
231226
232227 // Next, find all occurrences of linker-defined symbols that are _values_
233228 // of some symbol in the symbol table, and pointerize them too
@@ -421,12 +416,10 @@ the right behaviour for both implementations.
421416int linker_script_merget::ls_data2instructions (
422417 jsont &data,
423418 const std::string &linker_script,
424- goto_programt &gp,
425419 symbol_tablet &symbol_table,
426420 linker_valuest &linker_values)
427421#if 1
428422{
429- goto_programt::instructionst initialize_instructions=gp.instructions ;
430423 std::map<irep_idt, std::size_t > truncated_symbols;
431424 for (auto &d : to_json_array (data[" regions" ]))
432425 {
@@ -453,24 +446,46 @@ int linker_script_merget::ls_data2instructions(
453446
454447 constant_exprt array_size_expr=from_integer (array_size, size_type ());
455448 array_typet array_type (char_type (), array_size_expr);
456- symbol_exprt array_expr (array_name.str (), array_type);
457- source_locationt array_loc;
458449
450+ source_locationt array_loc;
459451 array_loc.set_file (linker_script);
460452 std::ostringstream array_comment;
461453 array_comment << " Object section '" << d[" section" ].value << " ' of size "
462454 << array_size << " bytes" ;
463455 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);
465473
466474 // 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 ())} ;
468476 address_of_exprt array_start (zero_idx);
469477
470478 // 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;
472486 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));
474489
475490 // Since the value of the pointer will be a random CBMC address, write a
476491 // note about the real address in the object file
@@ -494,22 +509,26 @@ int linker_script_merget::ls_data2instructions(
494509 << d[" section" ].value << " '. Original address in object file"
495510 << " is " << (*it)[" val" ].value ;
496511 start_loc.set_comment (start_comment.str ());
497- start_sym.add_source_location ()= start_loc;
512+ start_sym.location = start_loc;
498513
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;
505517
506518 if (has_end) // Same for pointer to end of array
507519 {
508520 plus_exprt array_end (array_start, array_size_expr);
509521
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;
511529 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));
513532
514533 auto entry = std::find_if (
515534 to_json_array (data[" addresses" ]).begin (),
@@ -531,37 +550,12 @@ int linker_script_merget::ls_data2instructions(
531550 << " '. Original address in object file"
532551 << " is " << (*entry)[" val" ].value ;
533552 end_loc.set_comment (end_comment.str ());
534- end_sym.add_source_location ()= end_loc;
553+ end_sym.location = end_loc;
535554
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;
541558 }
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);
565559 }
566560
567561 // 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(
597591 loc.set_comment (" linker script-defined symbol: char *" +
598592 d[" sym" ].value +" =" +" (char *)" +id2string (symbol_value)+" u;" );
599593
600- symbol_exprt lhs (d[" sym" ].value , pointer_type (char_type ()));
601-
602594 constant_exprt rhs (
603595 integer2bvrep (
604596 string2integer (id2string (symbol_value)),
@@ -607,14 +599,15 @@ int linker_script_merget::ls_data2instructions(
607599
608600 typecast_exprt rhs_tc (rhs, pointer_type (char_type ()));
609601
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;
612608
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));
618611 }
619612 return 0 ;
620613}
0 commit comments