Skip to content

Commit 6ef804c

Browse files
author
Daniel Kroening
authored
Merge pull request diffblue#1888 from tautschnig/linker-script-fixes
Linker-script processing fixes
2 parents a75c4f0 + b371e28 commit 6ef804c

File tree

5 files changed

+87
-62
lines changed

5 files changed

+87
-62
lines changed

src/goto-cc/compile.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -346,11 +346,8 @@ bool compilet::link()
346346
convert_symbols(compiled_functions);
347347

348348
// parse object files
349-
while(!object_files.empty())
349+
for(const auto &file_name : object_files)
350350
{
351-
std::string file_name=object_files.front();
352-
object_files.pop_front();
353-
354351
if(read_object_and_link(file_name, symbol_table,
355352
compiled_functions, get_message_handler()))
356353
return true;

src/goto-cc/dist-linux

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ mkdir /tmp/goto-cc-dist
1414
cp goto-cc /tmp/goto-cc-dist/
1515
cp ../goto-instrument/goto-instrument /tmp/goto-cc-dist/
1616
cp ../../LICENSE /tmp/goto-cc-dist/
17+
cp ../../scripts/ls_parse.py /tmp/goto-cc-dist/
1718
cd /tmp/goto-cc-dist
1819
tar cfz goto-cc-${VERSION_FILE}-linux.tgz goto-cc \
19-
goto-instrument LICENSE
20+
goto-instrument LICENSE ls_parse.py
2021

2122
echo Copying.
2223
scp goto-cc-${VERSION_FILE}-linux.tgz [email protected]:/home/www/cprover.org/goto-cc/download/

src/goto-cc/gcc_mode.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -813,7 +813,7 @@ int gcc_modet::run_gcc(const compilet &compiler)
813813
for(const auto &a : cmdline.parsed_argv)
814814
new_argv.push_back(a.arg);
815815

816-
if(compiler.wrote_object_files())
816+
if(!act_as_ld && compiler.wrote_object_files())
817817
{
818818
// Undefine all __CPROVER macros for the system compiler
819819
std::map<irep_idt, std::size_t> arities;
@@ -935,12 +935,7 @@ int gcc_modet::gcc_hybrid_binary(compilet &compiler)
935935
{
936936
linker_script_merget ls_merge(
937937
compiler, output_files, goto_binaries, cmdline, gcc_message_handler);
938-
const int fail=ls_merge.add_linker_script_definitions();
939-
if(fail!=0)
940-
{
941-
error() << "Unable to merge linker script symbols" << eom;
942-
return fail;
943-
}
938+
result=ls_merge.add_linker_script_definitions();
944939
}
945940

946941
// merge output from gcc with goto-binaries

src/goto-cc/linker_script_merge.cpp

Lines changed: 73 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,25 @@ int linker_script_merget::add_linker_script_definitions()
3838
const std::string &elf_file=*elf_binaries.begin();
3939
const std::string &goto_file=*goto_binaries.begin();
4040

41-
jsont data;
41+
temporary_filet linker_def_outfile("goto-cc-linker-info", ".json");
4242
std::list<irep_idt> linker_defined_symbols;
43-
int fail=get_linker_script_data(
44-
data, linker_defined_symbols, compiler.symbol_table, elf_file);
43+
int fail=
44+
get_linker_script_data(
45+
linker_defined_symbols,
46+
compiler.symbol_table,
47+
elf_file,
48+
linker_def_outfile());
49+
// ignore linker script parsing failures until the code is tested more widely
50+
if(fail!=0)
51+
return 0;
52+
53+
jsont data;
54+
fail=parse_json(linker_def_outfile(), get_message_handler(), data);
4555
if(fail!=0)
56+
{
57+
error() << "Problem parsing linker script JSON data" << eom;
4658
return fail;
59+
}
4760

4861
fail=linker_data_is_malformed(data);
4962
if(fail!=0)
@@ -117,8 +130,9 @@ linker_script_merget::linker_script_merget(
117130
replacement_predicates(
118131
{
119132
replacement_predicatet("address of array's first member",
120-
[](const exprt expr){ return to_symbol_expr(expr.op0().op0()); },
121-
[](const exprt expr)
133+
[](const exprt &expr) -> const symbol_exprt&
134+
{ return to_symbol_expr(expr.op0().op0()); },
135+
[](const exprt &expr, const namespacet &ns)
122136
{
123137
return expr.id()==ID_address_of &&
124138
expr.type().id()==ID_pointer &&
@@ -133,25 +147,39 @@ linker_script_merget::linker_script_merget(
133147
expr.op0().op1().type().id()==ID_signedbv;
134148
}),
135149
replacement_predicatet("address of array",
136-
[](const exprt expr){ return to_symbol_expr(expr.op0()); },
137-
[](const exprt expr)
150+
[](const exprt &expr) -> const symbol_exprt&
151+
{ return to_symbol_expr(expr.op0()); },
152+
[](const exprt &expr, const namespacet &ns)
138153
{
139154
return expr.id()==ID_address_of &&
140155
expr.type().id()==ID_pointer &&
141156

142157
expr.op0().id()==ID_symbol &&
143158
expr.op0().type().id()==ID_array;
144159
}),
160+
replacement_predicatet("address of struct",
161+
[](const exprt &expr) -> const symbol_exprt&
162+
{ return to_symbol_expr(expr.op0()); },
163+
[](const exprt &expr, const namespacet &ns)
164+
{
165+
return expr.id()==ID_address_of &&
166+
expr.type().id()==ID_pointer &&
167+
168+
expr.op0().id()==ID_symbol &&
169+
ns.follow(expr.op0().type()).id()==ID_struct;
170+
}),
145171
replacement_predicatet("array variable",
146-
[](const exprt expr){ return to_symbol_expr(expr); },
147-
[](const exprt expr)
172+
[](const exprt &expr) -> const symbol_exprt&
173+
{ return to_symbol_expr(expr); },
174+
[](const exprt &expr, const namespacet &ns)
148175
{
149176
return expr.id()==ID_symbol &&
150177
expr.type().id()==ID_array;
151178
}),
152179
replacement_predicatet("pointer (does not need pointerizing)",
153-
[](const exprt expr){ return to_symbol_expr(expr); },
154-
[](const exprt expr)
180+
[](const exprt &expr) -> const symbol_exprt&
181+
{ return to_symbol_expr(expr); },
182+
[](const exprt &expr, const namespacet &ns)
155183
{
156184
return expr.id()==ID_symbol &&
157185
expr.type().id()==ID_pointer;
@@ -164,6 +192,8 @@ int linker_script_merget::pointerize_linker_defined_symbols(
164192
symbol_tablet &symbol_table,
165193
const linker_valuest &linker_values)
166194
{
195+
const namespacet ns(symbol_table);
196+
167197
int ret=0;
168198
// First, pointerize the actual linker-defined symbols
169199
for(const auto &pair : linker_values)
@@ -191,7 +221,8 @@ int linker_script_merget::pointerize_linker_defined_symbols(
191221
int fail=pointerize_subexprs_of(
192222
symbol_table.get_writeable_ref(pair.first).value,
193223
to_pointerize,
194-
linker_values);
224+
linker_values,
225+
ns);
195226
if(to_pointerize.empty() && fail==0)
196227
continue;
197228
ret=1;
@@ -216,7 +247,8 @@ int linker_script_merget::pointerize_linker_defined_symbols(
216247
if(to_pointerize.empty())
217248
continue;
218249
debug() << "Pointerizing a program expression..." << eom;
219-
int fail=pointerize_subexprs_of(*insts, to_pointerize, linker_values);
250+
int fail = pointerize_subexprs_of(
251+
*insts, to_pointerize, linker_values, ns);
220252
if(to_pointerize.empty() && fail==0)
221253
continue;
222254
ret=1;
@@ -259,15 +291,17 @@ int linker_script_merget::replace_expr(
259291
int linker_script_merget::pointerize_subexprs_of(
260292
exprt &expr,
261293
std::list<symbol_exprt> &to_pointerize,
262-
const linker_valuest &linker_values)
294+
const linker_valuest &linker_values,
295+
const namespacet &ns)
263296
{
264297
int fail=0, tmp=0;
265298
for(auto const &pair : linker_values)
266299
for(auto const &pattern : replacement_predicates)
267300
{
268-
if(!pattern.match(expr))
301+
if(!pattern.match(expr, ns))
269302
continue;
270-
const symbol_exprt &inner_symbol=pattern.inner_symbol(expr);
303+
// take a copy, expr will be changed below
304+
const symbol_exprt inner_symbol=pattern.inner_symbol(expr);
271305
if(pair.first!=inner_symbol.get_identifier())
272306
continue;
273307
tmp=replace_expr(expr, linker_values, inner_symbol, pair.first,
@@ -292,7 +326,7 @@ int linker_script_merget::pointerize_subexprs_of(
292326

293327
for(auto &op : expr.operands())
294328
{
295-
tmp=pointerize_subexprs_of(op, to_pointerize, linker_values);
329+
tmp=pointerize_subexprs_of(op, to_pointerize, linker_values, ns);
296330
fail=tmp?tmp:fail;
297331
}
298332
return fail;
@@ -625,23 +659,24 @@ int linker_script_merget::ls_data2instructions(
625659
#endif
626660

627661
int linker_script_merget::get_linker_script_data(
628-
jsont &linker_data,
629662
std::list<irep_idt> &linker_defined_symbols,
630663
const symbol_tablet &symbol_table,
631-
const std::string &out_file)
664+
const std::string &out_file,
665+
const std::string &def_out_file)
632666
{
633667
for(auto const &pair : symbol_table.symbols)
634-
if(pair.second.is_extern && pair.second.value.is_nil()
635-
&& pair.second.name!="__CPROVER_memory")
668+
if(pair.second.is_extern && pair.second.value.is_nil() &&
669+
pair.second.name!="__CPROVER_memory")
636670
linker_defined_symbols.push_back(pair.second.name);
637671

638672
std::ostringstream linker_def_str;
639-
std::copy(linker_defined_symbols.begin(), linker_defined_symbols.end(),
640-
std::ostream_iterator<irep_idt>(linker_def_str, "\n"));
673+
std::copy(
674+
linker_defined_symbols.begin(),
675+
linker_defined_symbols.end(),
676+
std::ostream_iterator<irep_idt>(linker_def_str, "\n"));
641677
debug() << "Linker-defined symbols: [" << linker_def_str.str() << "]\n"
642678
<< eom;
643679

644-
temporary_filet linker_def_outfile("goto-cc-linker-info", ".json");
645680
temporary_filet linker_def_infile("goto-cc-linker-defs", "");
646681
std::ofstream linker_def_file(linker_def_infile());
647682
linker_def_file << linker_def_str.str();
@@ -653,29 +688,24 @@ int linker_script_merget::get_linker_script_data(
653688
"--script", cmdline.get_value('T'),
654689
"--object", out_file,
655690
"--sym-file", linker_def_infile(),
656-
"--out-file", linker_def_outfile()
691+
"--out-file", def_out_file
657692
};
658-
if(cmdline.isset("verbosity"))
659-
{
660-
unsigned verb=safe_string2unsigned(cmdline.get_value("verbosity"));
661-
if(verb>9)
662-
argv.push_back("--very-verbose");
663-
else if(verb>4)
664-
argv.push_back("--verbose");
665-
}
666693

667-
int rc=run(argv[0], argv, linker_def_infile(), linker_def_outfile());
694+
if(get_message_handler().get_verbosity()>9)
695+
argv.push_back("--very-verbose");
696+
else if(get_message_handler().get_verbosity()>4)
697+
argv.push_back("--verbose");
698+
699+
debug() << "RUN:";
700+
for(std::size_t i=0; i<argv.size(); i++)
701+
debug() << " " << argv[i];
702+
debug() << eom;
703+
704+
int rc=run(argv[0], argv, linker_def_infile(), def_out_file);
668705
if(rc!=0)
669-
{
670-
error() << "Problem parsing linker script" << eom;
671-
return rc;
672-
}
706+
warning() << "Problem parsing linker script" << eom;
673707

674-
int fail=parse_json(linker_def_outfile(), get_message_handler(),
675-
linker_data);
676-
if(fail!=0)
677-
error() << "Problem parsing linker script JSON data" << eom;
678-
return fail;
708+
return rc;
679709
}
680710

681711
int linker_script_merget::goto_and_object_mismatch(

src/goto-cc/linker_script_merge.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class replacement_predicatet
2626
replacement_predicatet(
2727
const std::string &description,
2828
const std::function<const symbol_exprt&(const exprt&)> inner_symbol,
29-
const std::function<bool(const exprt&)> match)
29+
const std::function<bool(const exprt&, const namespacet&)> match)
3030
: _description(description),
3131
_inner_symbol(inner_symbol),
3232
_match(match)
@@ -50,15 +50,15 @@ class replacement_predicatet
5050
/// If this function returns true, the entire expression should be replaced by
5151
/// a pointer whose underlying symbol is the symbol returned by
5252
/// replacement_predicatet::inner_symbol().
53-
const bool match(const exprt &expr) const
53+
const bool match(const exprt &expr, const namespacet &ns) const
5454
{
55-
return _match(expr);
55+
return _match(expr, ns);
5656
};
5757

5858
private:
5959
std::string _description;
6060
std::function<const symbol_exprt&(const exprt&)> _inner_symbol;
61-
std::function<bool(const exprt&)> _match;
61+
std::function<bool(const exprt&, const namespacet&)> _match;
6262
};
6363

6464
/// \brief Synthesise definitions of symbols that are defined in linker scripts
@@ -105,10 +105,10 @@ class linker_script_merget:public messaget
105105

106106
/// \brief Write linker script definitions to `linker_data`.
107107
int get_linker_script_data(
108-
jsont &linker_data,
109108
std::list<irep_idt> &linker_defined_symbols,
110109
const symbol_tablet &symbol_table,
111-
const std::string &out_file);
110+
const std::string &out_file,
111+
const std::string &def_out_file);
112112

113113
/// \brief Write a list of definitions derived from `data` into gp's
114114
/// `instructions` member.
@@ -165,6 +165,7 @@ class linker_script_merget:public messaget
165165
/// \param to_pointerize The symbols that are contained in the subexpressions
166166
/// that we will pointerize.
167167
/// \param linker_values the names of symbols defined in linker scripts.
168+
/// \param ns a namespace to look up types.
168169
///
169170
/// The subexpressions that we pointerize should be in one-to-one
170171
/// correspondence with the symbols in `to_pointerize`. Every time we
@@ -175,7 +176,8 @@ class linker_script_merget:public messaget
175176
int pointerize_subexprs_of(
176177
exprt &expr,
177178
std::list<symbol_exprt> &to_pointerize,
178-
const linker_valuest &linker_values);
179+
const linker_valuest &linker_values,
180+
const namespacet &ns);
179181

180182
/// \brief do the actual replacement of an expr with a new pointer expr
181183
int replace_expr(

0 commit comments

Comments
 (0)