Skip to content

Commit 36f81d6

Browse files
committed
Linking for weak symbols
1 parent db61ac8 commit 36f81d6

File tree

2 files changed

+58
-8
lines changed

2 files changed

+58
-8
lines changed

src/goto-programs/read_goto_binary.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -281,11 +281,13 @@ Function: link_functions
281281
static bool link_functions(
282282
symbol_tablet &dest_symbol_table,
283283
goto_functionst &dest_functions,
284-
symbol_tablet &src_symbol_table,
284+
const symbol_tablet &src_symbol_table,
285285
goto_functionst &src_functions,
286-
const rename_symbolt &rename_symbol)
286+
const rename_symbolt &rename_symbol,
287+
const hash_set_cont<irep_idt, irep_id_hash> &weak_symbols)
287288
{
288289
namespacet ns(dest_symbol_table);
290+
namespacet src_ns(src_symbol_table);
289291

290292
// merge functions
291293
Forall_goto_functions(src_it, src_functions)
@@ -320,15 +322,17 @@ static bool link_functions(
320322

321323
goto_functionst::goto_functiont &src_func=src_it->second;
322324

323-
if(in_dest_symbol_table.body.instructions.empty())
325+
if(in_dest_symbol_table.body.instructions.empty() ||
326+
weak_symbols.find(final_id)!=weak_symbols.end())
324327
{
325328
// the one with body wins!
326329
rename_symbols_in_function(src_func, rename_symbol);
327330

328331
in_dest_symbol_table.body.swap(src_func.body);
329332
in_dest_symbol_table.type=src_func.type;
330333
}
331-
else if(src_func.body.instructions.empty())
334+
else if(src_func.body.instructions.empty() ||
335+
src_ns.lookup(src_it->first).is_weak)
332336
{
333337
// just keep the old one in dest
334338
}
@@ -377,6 +381,12 @@ bool read_object_and_link(
377381
message_handler))
378382
return true;
379383

384+
typedef hash_set_cont<irep_idt, irep_id_hash> id_sett;
385+
id_sett weak_symbols;
386+
forall_symbols(it, symbol_table.symbols)
387+
if(it->second.is_weak)
388+
weak_symbols.insert(it->first);
389+
380390
linkingt linking(symbol_table,
381391
temp_model.symbol_table,
382392
message_handler);
@@ -386,7 +396,7 @@ bool read_object_and_link(
386396

387397
if(link_functions(symbol_table, functions,
388398
temp_model.symbol_table, temp_model.goto_functions,
389-
linking.rename_symbol))
399+
linking.rename_symbol, weak_symbols))
390400
return true;
391401

392402
return false;

src/linking/linking.cpp

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,9 @@ bool linkingt::needs_renaming_non_type(
502502
// These are static functions, or static variables
503503
// inside static function bodies.
504504
if(new_symbol.is_file_local ||
505-
old_symbol.is_file_local)
505+
old_symbol.is_file_local ||
506+
(new_symbol.is_weak &&
507+
old_symbol.is_weak))
506508
return true;
507509

508510
return false;
@@ -542,6 +544,7 @@ void linkingt::duplicate_code_symbol(
542544

543545
old_symbol.type=new_symbol.type;
544546
old_symbol.location=new_symbol.location;
547+
old_symbol.is_weak=new_symbol.is_weak;
545548
}
546549
else if(!new_symbol.location.get_function().empty() &&
547550
new_symbol.value.is_nil())
@@ -561,6 +564,42 @@ void linkingt::duplicate_code_symbol(
561564
{
562565
old_symbol.type=new_symbol.type;
563566
old_symbol.location=new_symbol.location;
567+
old_symbol.is_weak=new_symbol.is_weak;
568+
}
569+
}
570+
// replace weak symbols
571+
else if(old_symbol.is_weak)
572+
{
573+
if(new_symbol.value.is_nil())
574+
link_warning(
575+
old_symbol,
576+
new_symbol,
577+
"function declaration conflicts with with weak definition");
578+
else
579+
{
580+
// new weak symbol should have been renamed
581+
assert(!new_symbol.is_weak);
582+
old_symbol.value.make_nil();
583+
old_symbol.is_weak=false;
584+
}
585+
}
586+
else if(new_symbol.is_weak)
587+
{
588+
if(new_symbol.value.is_nil() ||
589+
old_symbol.value.is_not_nil())
590+
{
591+
new_symbol.value.make_nil();
592+
593+
link_warning(
594+
old_symbol,
595+
new_symbol,
596+
"ignoring conflicting weak function declaration");
597+
}
598+
else
599+
{
600+
// new weak symbol should have been renamed
601+
assert(!old_symbol.is_weak);
602+
old_symbol.is_weak=true;
564603
}
565604
}
566605
// mismatch on number of parameters is definitively an error
@@ -845,12 +884,13 @@ void linkingt::duplicate_object_symbol(
845884
!new_symbol.value.get_bool(ID_C_zero_initializer))
846885
{
847886
if(old_symbol.value.is_nil() ||
848-
old_symbol.value.get_bool(ID_C_zero_initializer))
887+
old_symbol.value.get_bool(ID_C_zero_initializer) ||
888+
old_symbol.is_weak)
849889
{
850890
// new_symbol wins
851891
old_symbol.value=new_symbol.value;
852892
}
853-
else
893+
else if(!new_symbol.is_weak)
854894
{
855895
// try simplifier
856896
exprt tmp_old=old_symbol.value,

0 commit comments

Comments
 (0)