Skip to content

Commit b371e28

Browse files
committed
Linker-scripts: support linker symbols with struct type
The Linux kernel reads boot-command line parameters from a struct stored at a link-time defined location. cr https://code.amazon.com/reviews/CR-1470784
1 parent e999552 commit b371e28

File tree

2 files changed

+32
-14
lines changed

2 files changed

+32
-14
lines changed

src/goto-cc/linker_script_merge.cpp

+25-9
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ linker_script_merget::linker_script_merget(
132132
replacement_predicatet("address of array's first member",
133133
[](const exprt &expr) -> const symbol_exprt&
134134
{ return to_symbol_expr(expr.op0().op0()); },
135-
[](const exprt expr)
135+
[](const exprt &expr, const namespacet &ns)
136136
{
137137
return expr.id()==ID_address_of &&
138138
expr.type().id()==ID_pointer &&
@@ -149,26 +149,37 @@ linker_script_merget::linker_script_merget(
149149
replacement_predicatet("address of array",
150150
[](const exprt &expr) -> const symbol_exprt&
151151
{ return to_symbol_expr(expr.op0()); },
152-
[](const exprt expr)
152+
[](const exprt &expr, const namespacet &ns)
153153
{
154154
return expr.id()==ID_address_of &&
155155
expr.type().id()==ID_pointer &&
156156

157157
expr.op0().id()==ID_symbol &&
158158
expr.op0().type().id()==ID_array;
159159
}),
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+
}),
160171
replacement_predicatet("array variable",
161172
[](const exprt &expr) -> const symbol_exprt&
162173
{ return to_symbol_expr(expr); },
163-
[](const exprt expr)
174+
[](const exprt &expr, const namespacet &ns)
164175
{
165176
return expr.id()==ID_symbol &&
166177
expr.type().id()==ID_array;
167178
}),
168179
replacement_predicatet("pointer (does not need pointerizing)",
169180
[](const exprt &expr) -> const symbol_exprt&
170181
{ return to_symbol_expr(expr); },
171-
[](const exprt expr)
182+
[](const exprt &expr, const namespacet &ns)
172183
{
173184
return expr.id()==ID_symbol &&
174185
expr.type().id()==ID_pointer;
@@ -181,6 +192,8 @@ int linker_script_merget::pointerize_linker_defined_symbols(
181192
symbol_tablet &symbol_table,
182193
const linker_valuest &linker_values)
183194
{
195+
const namespacet ns(symbol_table);
196+
184197
int ret=0;
185198
// First, pointerize the actual linker-defined symbols
186199
for(const auto &pair : linker_values)
@@ -208,7 +221,8 @@ int linker_script_merget::pointerize_linker_defined_symbols(
208221
int fail=pointerize_subexprs_of(
209222
symbol_table.get_writeable_ref(pair.first).value,
210223
to_pointerize,
211-
linker_values);
224+
linker_values,
225+
ns);
212226
if(to_pointerize.empty() && fail==0)
213227
continue;
214228
ret=1;
@@ -233,7 +247,8 @@ int linker_script_merget::pointerize_linker_defined_symbols(
233247
if(to_pointerize.empty())
234248
continue;
235249
debug() << "Pointerizing a program expression..." << eom;
236-
int fail=pointerize_subexprs_of(*insts, to_pointerize, linker_values);
250+
int fail = pointerize_subexprs_of(
251+
*insts, to_pointerize, linker_values, ns);
237252
if(to_pointerize.empty() && fail==0)
238253
continue;
239254
ret=1;
@@ -276,13 +291,14 @@ int linker_script_merget::replace_expr(
276291
int linker_script_merget::pointerize_subexprs_of(
277292
exprt &expr,
278293
std::list<symbol_exprt> &to_pointerize,
279-
const linker_valuest &linker_values)
294+
const linker_valuest &linker_values,
295+
const namespacet &ns)
280296
{
281297
int fail=0, tmp=0;
282298
for(auto const &pair : linker_values)
283299
for(auto const &pattern : replacement_predicates)
284300
{
285-
if(!pattern.match(expr))
301+
if(!pattern.match(expr, ns))
286302
continue;
287303
// take a copy, expr will be changed below
288304
const symbol_exprt inner_symbol=pattern.inner_symbol(expr);
@@ -310,7 +326,7 @@ int linker_script_merget::pointerize_subexprs_of(
310326

311327
for(auto &op : expr.operands())
312328
{
313-
tmp=pointerize_subexprs_of(op, to_pointerize, linker_values);
329+
tmp=pointerize_subexprs_of(op, to_pointerize, linker_values, ns);
314330
fail=tmp?tmp:fail;
315331
}
316332
return fail;

src/goto-cc/linker_script_merge.h

+7-5
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
@@ -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)