Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 0667ded

Browse files
committedFeb 12, 2021
Move link_goto_model to read_goto_binary.cpp
This is the only code that uses the functions from link_goto_model.{h,cpp}, and those functions weren't an easily usable API anyway as a certain protocol needs to be followed.
1 parent cff53ce commit 0667ded

File tree

6 files changed

+195
-246
lines changed

6 files changed

+195
-246
lines changed
 

‎scripts/expected_doxygen_warnings.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@
8282
warning: Include graph for 'cbmc_parse_options.cpp' not generated, too many nodes (61), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES.
8383
warning: Include graph for 'goto_instrument_parse_options.cpp' not generated, too many nodes (97), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES.
8484
warning: Included by graph for 'goto_functions.h' not generated, too many nodes (66), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES.
85-
warning: Included by graph for 'goto_model.h' not generated, too many nodes (109), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES.
85+
warning: Included by graph for 'goto_model.h' not generated, too many nodes (108), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES.
8686
warning: Included by graph for 'arith_tools.h' not generated, too many nodes (182), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES.
8787
warning: Included by graph for 'c_types.h' not generated, too many nodes (111), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES.
8888
warning: Included by graph for 'config.h' not generated, too many nodes (85), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES.

‎src/goto-programs/Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ SRC = add_malloc_may_fail_variable_initializations.cpp \
3030
json_expr.cpp \
3131
json_goto_trace.cpp \
3232
label_function_pointer_call_sites.cpp \
33-
link_goto_model.cpp \
3433
link_to_library.cpp \
3534
loop_ids.cpp \
3635
mm_io.cpp \

‎src/goto-programs/README.md

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -567,15 +567,6 @@ deserialises the passed file into a temporary `::goto_modelt` instance, and
567567
then it performs 'linking' of the temporary into a passed destination
568568
`::goto_modelt` instance.
569569

570-
Details about linking of `::goto_modelt` instances can be found
571-
[here](\ref section-linking-goto-models).
572-
573-
\section section-linking-goto-models Linking Goto Models
574-
575-
C++ modules:
576-
- `link_goto_model.h`
577-
- `link_goto_model.cpp`
578-
579570
Dependencies:
580571
- [linking folder](\ref linking).
581572
- [typecheck](\ref section-goto-typecheck).

‎src/goto-programs/link_goto_model.cpp

Lines changed: 0 additions & 205 deletions
This file was deleted.

‎src/goto-programs/link_goto_model.h

Lines changed: 0 additions & 29 deletions
This file was deleted.

‎src/goto-programs/read_goto_binary.cpp

Lines changed: 194 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,212 @@ Module: Read Goto Programs
1414
#include <fstream>
1515
#include <unordered_set>
1616

17+
#include <util/base_type.h>
1718
#include <util/config.h>
19+
#include <util/exception_utils.h>
1820
#include <util/message.h>
1921
#include <util/rename_symbol.h>
2022
#include <util/replace_symbol.h>
23+
#include <util/symbol.h>
2124
#include <util/tempfile.h>
2225
#include <util/unicode.h>
2326

27+
#include <linking/linking_class.h>
28+
2429
#include "goto_model.h"
25-
#include "link_goto_model.h"
2630
#include "read_bin_goto_object.h"
2731
#include "elf_reader.h"
2832
#include "osx_fat_reader.h"
2933

34+
static void rename_symbols_in_function(
35+
goto_functionst::goto_functiont &function,
36+
irep_idt &new_function_name,
37+
const rename_symbolt &rename_symbol)
38+
{
39+
for(auto &identifier : function.parameter_identifiers)
40+
{
41+
auto entry = rename_symbol.expr_map.find(identifier);
42+
if(entry != rename_symbol.expr_map.end())
43+
identifier = entry->second;
44+
}
45+
46+
goto_programt &program = function.body;
47+
48+
Forall_goto_program_instructions(iit, program)
49+
{
50+
rename_symbol(iit->code);
51+
52+
if(iit->has_condition())
53+
{
54+
exprt c = iit->get_condition();
55+
rename_symbol(c);
56+
iit->set_condition(c);
57+
}
58+
}
59+
}
60+
61+
/// Link a set of goto functions, considering weak symbols
62+
/// and symbol renaming
63+
static bool link_functions(
64+
symbol_tablet &dest_symbol_table,
65+
goto_functionst &dest_functions,
66+
const symbol_tablet &src_symbol_table,
67+
goto_functionst &src_functions,
68+
const rename_symbolt &rename_symbol,
69+
const std::unordered_set<irep_idt> &weak_symbols)
70+
{
71+
namespacet ns(dest_symbol_table);
72+
namespacet src_ns(src_symbol_table);
73+
74+
// merge functions
75+
for(auto &gf_entry : src_functions.function_map)
76+
{
77+
// the function might have been renamed
78+
rename_symbolt::expr_mapt::const_iterator e_it =
79+
rename_symbol.expr_map.find(gf_entry.first);
80+
81+
irep_idt final_id = gf_entry.first;
82+
83+
if(e_it != rename_symbol.expr_map.end())
84+
final_id = e_it->second;
85+
86+
// already there?
87+
goto_functionst::function_mapt::iterator dest_f_it =
88+
dest_functions.function_map.find(final_id);
89+
90+
goto_functionst::goto_functiont &src_func = gf_entry.second;
91+
if(dest_f_it == dest_functions.function_map.end()) // not there yet
92+
{
93+
rename_symbols_in_function(src_func, final_id, rename_symbol);
94+
dest_functions.function_map.emplace(final_id, std::move(src_func));
95+
}
96+
else // collision!
97+
{
98+
goto_functionst::goto_functiont &in_dest_symbol_table = dest_f_it->second;
99+
100+
if(
101+
in_dest_symbol_table.body.instructions.empty() ||
102+
weak_symbols.find(final_id) != weak_symbols.end())
103+
{
104+
// the one with body wins!
105+
rename_symbols_in_function(src_func, final_id, rename_symbol);
106+
107+
in_dest_symbol_table.body.swap(src_func.body);
108+
in_dest_symbol_table.parameter_identifiers.swap(
109+
src_func.parameter_identifiers);
110+
}
111+
else if(
112+
src_func.body.instructions.empty() ||
113+
src_ns.lookup(gf_entry.first).is_weak)
114+
{
115+
// just keep the old one in dest
116+
}
117+
else if(to_code_type(ns.lookup(final_id).type).get_inlined())
118+
{
119+
// ok, we silently ignore
120+
}
121+
else
122+
{
123+
// the linking code will have ensured that types match
124+
}
125+
}
126+
}
127+
128+
return false;
129+
}
130+
131+
static void link_goto_model(
132+
goto_modelt &dest,
133+
goto_modelt &src,
134+
unchecked_replace_symbolt &object_type_updates,
135+
message_handlert &message_handler)
136+
{
137+
std::unordered_set<irep_idt> weak_symbols;
138+
139+
for(const auto &symbol_pair : dest.symbol_table.symbols)
140+
{
141+
if(symbol_pair.second.is_weak)
142+
weak_symbols.insert(symbol_pair.first);
143+
}
144+
145+
linkingt linking(dest.symbol_table, src.symbol_table, message_handler);
146+
147+
if(linking.typecheck_main())
148+
throw invalid_source_file_exceptiont("typechecking main failed");
149+
150+
if(link_functions(
151+
dest.symbol_table,
152+
dest.goto_functions,
153+
src.symbol_table,
154+
src.goto_functions,
155+
linking.rename_symbol,
156+
weak_symbols))
157+
{
158+
throw invalid_source_file_exceptiont("linking failed");
159+
}
160+
161+
object_type_updates.get_expr_map().insert(
162+
linking.object_type_updates.get_expr_map().begin(),
163+
linking.object_type_updates.get_expr_map().end());
164+
}
165+
166+
static void finalize_linking(
167+
goto_modelt &dest,
168+
const unchecked_replace_symbolt &object_type_updates)
169+
{
170+
goto_functionst &dest_functions = dest.goto_functions;
171+
symbol_tablet &dest_symbol_table = dest.symbol_table;
172+
173+
// apply macros
174+
rename_symbolt macro_application;
175+
176+
for(const auto &symbol_pair : dest_symbol_table.symbols)
177+
{
178+
if(symbol_pair.second.is_macro && !symbol_pair.second.is_type)
179+
{
180+
const symbolt &symbol = symbol_pair.second;
181+
182+
INVARIANT(symbol.value.id() == ID_symbol, "must have symbol");
183+
const irep_idt &id = to_symbol_expr(symbol.value).get_identifier();
184+
185+
#if 0
186+
if(!base_type_eq(symbol.type, ns.lookup(id).type, ns))
187+
{
188+
std::cerr << symbol << '\n';
189+
std::cerr << ns.lookup(id) << '\n';
190+
}
191+
INVARIANT(base_type_eq(symbol.type, ns.lookup(id).type, ns),
192+
"type matches");
193+
#endif
194+
195+
macro_application.insert_expr(symbol.name, id);
196+
}
197+
}
198+
199+
if(!macro_application.expr_map.empty())
200+
{
201+
for(auto &gf_entry : dest_functions.function_map)
202+
{
203+
irep_idt final_id = gf_entry.first;
204+
rename_symbols_in_function(gf_entry.second, final_id, macro_application);
205+
}
206+
}
207+
208+
if(!object_type_updates.empty())
209+
{
210+
for(auto &gf_entry : dest_functions.function_map)
211+
{
212+
Forall_goto_program_instructions(iit, gf_entry.second.body)
213+
{
214+
iit->transform([&object_type_updates](exprt expr) {
215+
object_type_updates(expr);
216+
return expr;
217+
});
218+
}
219+
}
220+
}
221+
}
222+
30223
static bool read_goto_binary(
31224
const std::string &filename,
32225
symbol_tablet &,

0 commit comments

Comments
 (0)
Please sign in to comment.