Prevent frontend function confusion (#383)

Function symbols can clash as we compile multiple YUL `object`
definition into the same `LLVM` module.
- Disambiguate via unique function symbols based its location (runtime
or deploy code).
- Use `LinkOnceODR` linkage for compiler builtin helpers.

---------

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
This commit is contained in:
xermicus
2025-09-29 23:05:57 +02:00
committed by GitHub
parent 6858cb9a61
commit b560d72139
12 changed files with 103 additions and 58 deletions
@@ -30,8 +30,9 @@ pub trait RuntimeFunction {
Self::NAME,
Self::r#type(context),
0,
Some(inkwell::module::Linkage::External), // TODO: `Private` emits unrelocated AUIPC?
Some(inkwell::module::Linkage::LinkOnceODR),
None,
false,
)?;
let mut attributes = Self::ATTRIBUTES.to_vec();
@@ -45,6 +46,12 @@ pub trait RuntimeFunction {
&attributes,
true,
);
let function = function.borrow().declaration().function_value();
let comdat = context
.module()
.get_or_insert_comdat(&format!("{}_comdat", Self::NAME));
comdat.set_selection_kind(inkwell::comdat::ComdatSelectionKind::NoDuplicates);
function.as_global_value().set_comdat(comdat);
Ok(())
}
@@ -52,7 +59,7 @@ pub trait RuntimeFunction {
/// Get the function declaration.
fn declaration<'ctx>(context: &Context<'ctx>) -> Declaration<'ctx> {
context
.get_function(Self::NAME)
.get_function(Self::NAME, false)
.unwrap_or_else(|| panic!("runtime function {} should be declared", Self::NAME))
.borrow()
.declaration()
@@ -60,7 +67,7 @@ pub trait RuntimeFunction {
/// Emit the function.
fn emit(&self, context: &mut Context) -> anyhow::Result<()> {
context.set_current_function(Self::NAME, None)?;
context.set_current_function(Self::NAME, None, false)?;
context.set_basic_block(context.current_function().borrow().entry_block());
let return_value = self.emit_body(context)?;
@@ -99,7 +106,7 @@ pub trait RuntimeFunction {
) -> inkwell::values::BasicValueEnum<'ctx> {
let name = Self::NAME;
context
.get_function(name)
.get_function(name, false)
.unwrap_or_else(|| panic!("runtime function {name} should be declared"))
.borrow()
.declaration()