mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-06-12 15:11:02 +00:00
mark internal functions linker private (#381)
Prevents unused functions in the emitted ELF object. Drive-by add a missing test case (which misses a relocation under `-Oz` when all internal functions are marked as private). --------- Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
//! The LLVM module build.
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use revive_common::BYTE_LENGTH_WORD;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
@@ -17,8 +15,6 @@ pub struct Build {
|
||||
pub bytecode: Vec<u8>,
|
||||
/// The PolkaVM bytecode hash. Unlinked builds don't have a hash yet.
|
||||
pub bytecode_hash: Option<[u8; BYTE_LENGTH_WORD]>,
|
||||
/// The hash-to-full-path mapping of the contract factory dependencies.
|
||||
pub factory_dependencies: BTreeMap<String, String>,
|
||||
}
|
||||
|
||||
impl Build {
|
||||
@@ -29,7 +25,6 @@ impl Build {
|
||||
metadata_hash,
|
||||
bytecode,
|
||||
bytecode_hash: None,
|
||||
factory_dependencies: BTreeMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,24 +64,13 @@ impl<'ctx> LLVMRuntime<'ctx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Declares an LLVM runtime function in the `module`,
|
||||
pub fn declare(
|
||||
module: &inkwell::module::Module<'ctx>,
|
||||
name: &str,
|
||||
r#type: inkwell::types::FunctionType<'ctx>,
|
||||
linkage: Option<inkwell::module::Linkage>,
|
||||
) -> FunctionDeclaration<'ctx> {
|
||||
let value = module.add_function(name, r#type, linkage);
|
||||
FunctionDeclaration::new(r#type, value)
|
||||
}
|
||||
|
||||
/// Create the function definition from an existing symbol.
|
||||
pub fn define(
|
||||
module: &inkwell::module::Module<'ctx>,
|
||||
name: &str,
|
||||
) -> Option<FunctionDeclaration<'ctx>> {
|
||||
let value = module.get_function(name)?;
|
||||
value.set_linkage(inkwell::module::Linkage::External);
|
||||
value.set_linkage(inkwell::module::Linkage::Private);
|
||||
FunctionDeclaration::new(value.get_type(), value).into()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,15 +75,6 @@ impl<'ctx> Function<'ctx> {
|
||||
self.name.as_str()
|
||||
}
|
||||
|
||||
/// Checks whether the function is defined outside of the front-end.
|
||||
pub fn is_name_external(name: &str) -> bool {
|
||||
name.starts_with("llvm.")
|
||||
|| (name.starts_with("__")
|
||||
&& name != self::runtime::FUNCTION_ENTRY
|
||||
&& name != self::runtime::FUNCTION_DEPLOY_CODE
|
||||
&& name != self::runtime::FUNCTION_RUNTIME_CODE)
|
||||
}
|
||||
|
||||
/// Returns the LLVM function declaration.
|
||||
pub fn declaration(&self) -> Declaration<'ctx> {
|
||||
self.declaration
|
||||
@@ -223,30 +214,11 @@ impl<'ctx> Function<'ctx> {
|
||||
self.stack.get(name).copied()
|
||||
}
|
||||
|
||||
/// Removes the pointer to a stack variable.
|
||||
pub fn remove_stack_pointer(&mut self, name: &str) {
|
||||
self.stack.remove(name);
|
||||
}
|
||||
|
||||
/// Returns the return entity representation.
|
||||
pub fn r#return(&self) -> Return<'ctx> {
|
||||
self.r#return
|
||||
}
|
||||
|
||||
/// Returns the pointer to the function return value.
|
||||
/// # Panics
|
||||
/// If the pointer has not been set yet.
|
||||
pub fn return_pointer(&self) -> Option<Pointer<'ctx>> {
|
||||
self.r#return.return_pointer()
|
||||
}
|
||||
|
||||
/// Returns the return data size in bytes, based on the default stack alignment.
|
||||
/// # Panics
|
||||
/// If the pointer has not been set yet.
|
||||
pub fn return_data_size(&self) -> usize {
|
||||
self.r#return.return_data_size()
|
||||
}
|
||||
|
||||
/// Returns the function entry block.
|
||||
pub fn entry_block(&self) -> inkwell::basic_block::BasicBlock<'ctx> {
|
||||
self.entry_block
|
||||
|
||||
@@ -36,7 +36,7 @@ where
|
||||
runtime::FUNCTION_DEPLOY_CODE,
|
||||
function_type,
|
||||
0,
|
||||
Some(inkwell::module::Linkage::External),
|
||||
Some(inkwell::module::Linkage::Private),
|
||||
None,
|
||||
)?;
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ where
|
||||
runtime::FUNCTION_RUNTIME_CODE,
|
||||
function_type,
|
||||
0,
|
||||
Some(inkwell::module::Linkage::External),
|
||||
Some(inkwell::module::Linkage::Private),
|
||||
None,
|
||||
)?;
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ pub trait RuntimeFunction {
|
||||
Self::NAME,
|
||||
Self::r#type(context),
|
||||
0,
|
||||
Some(inkwell::module::Linkage::External),
|
||||
Some(inkwell::module::Linkage::External), // TODO: `Private` emits unrelocated AUIPC?
|
||||
None,
|
||||
)?;
|
||||
|
||||
|
||||
@@ -83,7 +83,19 @@ pub fn link(
|
||||
let bytecode_linked = ElfLinker::setup()?.link(bytecode, symbols.as_slice())?;
|
||||
polkavm_linker(&bytecode_linked, strip_binary)
|
||||
.map(|pvm| (pvm, ObjectFormat::PVM))
|
||||
.unwrap_or_else(|_| (bytecode.to_vec(), ObjectFormat::ELF))
|
||||
.unwrap_or_else(|error| {
|
||||
if !error
|
||||
.to_string()
|
||||
.lines()
|
||||
.map(|line| line.trim())
|
||||
.filter(|line| !line.is_empty())
|
||||
.all(|line| line.contains("found undefined symbol"))
|
||||
{
|
||||
panic!("ICE: linker: {error}");
|
||||
}
|
||||
|
||||
(bytecode.to_vec(), ObjectFormat::ELF)
|
||||
})
|
||||
}
|
||||
Err(error) => panic!("ICE: linker: {error}"),
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user