Skip to content

Commit fac41f2

Browse files
committed
Section renaming must be applied across translation units
The Unix linker starts with symbols placed in the "common" pseudo-section and will then match them with definitions located in other sections. Similarly, we need to make sure that symbols across translation units are matched up, and macros will make sure that's the case.
1 parent 79218f0 commit fac41f2

File tree

6 files changed

+68
-2
lines changed

6 files changed

+68
-2
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include <assert.h>
2+
3+
int in_other_section(void);
4+
int also_in_other_section(void);
5+
6+
int main()
7+
{
8+
#ifdef __GNUC__
9+
assert(in_other_section() == 42);
10+
assert(also_in_other_section() == 42);
11+
#endif
12+
return 0;
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#ifdef __GNUC__
2+
int in_other_section(void);
3+
4+
int __attribute__((__section__(".init.text"))) in_other_section(void)
5+
{
6+
return 42;
7+
}
8+
9+
int __attribute__((__section__(".init.text"))) also_in_other_section(void)
10+
{
11+
return 42;
12+
}
13+
#endif
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
main.c
3+
section.c
4+
^VERIFICATION SUCCESSFUL$
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
--
8+
^warning: ignoring
9+
^CONVERSION ERROR$

src/ansi-c/c_typecheck_base.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,28 @@ void c_typecheck_baset::typecheck_declaration(
758758
else
759759
asm_name+=id2string(symbol.name);
760760

761+
if(!symbol.is_file_local)
762+
{
763+
// create a macro to apply section renaming across translation units
764+
symbolt section_macro = symbol;
765+
section_macro.value = symbol_exprt::typeless(asm_name);
766+
section_macro.is_macro = true;
767+
768+
// replace a preceding "extern" declaration, or try to insert a new
769+
// symbol
770+
auto dest = symbol_table.get_writeable(symbol.name);
771+
if(dest && dest->value.is_nil())
772+
{
773+
*dest = section_macro;
774+
}
775+
else if(!symbol_table.insert(section_macro).second)
776+
{
777+
warning().source_location = symbol.location;
778+
warning() << "symbol '" << symbol.name
779+
<< "' exists in multiple sections" << eom;
780+
}
781+
}
782+
761783
apply_asm_label(asm_name, symbol);
762784
}
763785

src/goto-programs/goto_convert_functions.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,11 @@ void goto_convert_functionst::convert_function(
160160
f.set_parameter_identifiers(code_type);
161161

162162
if(
163-
symbol.value.is_nil() ||
163+
symbol.is_macro || symbol.value.is_nil() ||
164164
symbol.is_compiled()) /* goto_inline may have removed the body */
165+
{
165166
return;
167+
}
166168

167169
// we have a body, make sure all parameter names are valid
168170
for(const auto &p : f.parameter_identifiers)

src/linking/remove_internal_symbols.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,17 @@ void remove_internal_symbols(
135135
is_file_local=false;
136136
}
137137

138-
if(is_type || symbol.is_macro)
138+
if(is_type)
139139
{
140140
// never EXPORTED by itself
141141
}
142+
else if(
143+
symbol.is_macro &&
144+
static_cast<const exprt &>(symbol.value).type() != typet{})
145+
{
146+
// only (typeless) export macros that do renaming, e.g., section renaming
147+
// as implemented in the C front-end
148+
}
142149
else if(is_function)
143150
{
144151
// body? not local (i.e., "static")?

0 commit comments

Comments
 (0)