mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 07:41:12 +00:00
Add linker data for strings, and deduplicate them
For references to addresses of constant strings, we make an entry in reloc.CODE and configure the relocation type to say it points at a memory address. (At least I think this is right, I can't test it yet!) The same info can also be used for de-duplication. It turns out we don't need reloc.DATA. I had misunderstood it. The use case for that would be constant nested data structures, where constant data would contain pointers to other constant data. I don't think we're doing this in Roc at all, but not sure.
This commit is contained in:
parent
2f0296a5fa
commit
38d9fc5bbd
5 changed files with 113 additions and 65 deletions
|
@ -5,7 +5,7 @@ use std::fmt::Debug;
|
|||
|
||||
use roc_module::symbol::Symbol;
|
||||
|
||||
use super::linking::{IndexRelocType, RelocationEntry};
|
||||
use super::linking::{IndexRelocType, OffsetRelocType, RelocationEntry};
|
||||
use super::opcodes::*;
|
||||
use super::serialize::{SerialBuffer, Serialize};
|
||||
use crate::{round_up_to_alignment, FRAME_ALIGNMENT_BYTES, STACK_POINTER_GLOBAL_ID};
|
||||
|
@ -461,6 +461,16 @@ impl<'a> CodeBuilder<'a> {
|
|||
self.code.encode_u32(offset);
|
||||
}
|
||||
|
||||
/// Insert a linker relocation for a memory address
|
||||
pub fn insert_memory_relocation(&mut self, symbol_index: u32) {
|
||||
self.relocations.push(RelocationEntry::Offset {
|
||||
type_id: OffsetRelocType::MemoryAddrLeb,
|
||||
offset: self.code.len() as u32,
|
||||
symbol_index,
|
||||
addend: 0,
|
||||
});
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
|
||||
INSTRUCTION METHODS
|
||||
|
|
|
@ -303,11 +303,12 @@ impl Serialize for WasmObjectSymbol {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum DataSymbol {
|
||||
Defined {
|
||||
name: String,
|
||||
index: u32,
|
||||
offset: u32,
|
||||
segment_index: u32,
|
||||
segment_offset: u32,
|
||||
size: u32,
|
||||
},
|
||||
Imported {
|
||||
|
@ -320,14 +321,14 @@ impl Serialize for DataSymbol {
|
|||
match self {
|
||||
Self::Defined {
|
||||
name,
|
||||
index,
|
||||
offset,
|
||||
segment_index,
|
||||
segment_offset,
|
||||
size,
|
||||
} => {
|
||||
buffer.encode_u32(name.len() as u32);
|
||||
buffer.append_slice(name.as_bytes());
|
||||
buffer.encode_u32(*index);
|
||||
buffer.encode_u32(*offset);
|
||||
buffer.encode_u32(*segment_index);
|
||||
buffer.encode_u32(*segment_offset);
|
||||
buffer.encode_u32(*size);
|
||||
}
|
||||
Self::Imported { name } => {
|
||||
|
@ -367,6 +368,13 @@ impl SymInfo {
|
|||
info: SymInfoFields::Function(linking_symbol),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn for_data(data_symbol: DataSymbol) -> Self {
|
||||
SymInfo {
|
||||
flags: 0,
|
||||
info: SymInfoFields::Data(data_symbol),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for SymInfo {
|
||||
|
|
|
@ -614,8 +614,7 @@ pub struct WasmModule<'a> {
|
|||
pub code: CodeSection<'a>,
|
||||
pub data: DataSection<'a>,
|
||||
pub linking: LinkingSection<'a>,
|
||||
pub reloc_code: RelocationSection<'a>,
|
||||
pub reloc_data: RelocationSection<'a>,
|
||||
pub relocations: RelocationSection<'a>,
|
||||
}
|
||||
|
||||
impl<'a> WasmModule<'a> {
|
||||
|
@ -654,22 +653,16 @@ impl<'a> WasmModule<'a> {
|
|||
let data_count_section = DataCountSection::new(&self.data);
|
||||
counter.serialize_and_count(buffer, &data_count_section);
|
||||
|
||||
// Code section mutates its linker relocation data during serialization
|
||||
// Code section is the only one with relocations so we can stop counting
|
||||
let code_section_index = counter.section_index;
|
||||
self.code
|
||||
.serialize_with_relocs(buffer, &mut self.reloc_code.entries);
|
||||
counter.update(buffer);
|
||||
.serialize_with_relocs(buffer, &mut self.relocations.entries);
|
||||
|
||||
// Data section is the last one before linking, so we can stop counting
|
||||
let data_section_index = counter.section_index;
|
||||
self.data.serialize(buffer);
|
||||
|
||||
self.linking.serialize(buffer);
|
||||
|
||||
self.reloc_code.target_section_index = Some(code_section_index);
|
||||
self.reloc_code.serialize(buffer);
|
||||
|
||||
self.reloc_data.target_section_index = Some(data_section_index);
|
||||
self.reloc_data.serialize(buffer);
|
||||
self.relocations.target_section_index = Some(code_section_index);
|
||||
self.relocations.serialize(buffer);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue