mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 15:21:12 +00:00
Rough draft of function name relocations
This commit is contained in:
parent
f5f34b74c0
commit
9780cce4dd
4 changed files with 135 additions and 67 deletions
|
@ -27,10 +27,10 @@ pub struct WasmBackend<'a> {
|
||||||
// Module-level data
|
// Module-level data
|
||||||
pub module_builder: ModuleBuilder,
|
pub module_builder: ModuleBuilder,
|
||||||
pub code_section_bytes: std::vec::Vec<u8>,
|
pub code_section_bytes: std::vec::Vec<u8>,
|
||||||
|
pub call_relocations: Vec<'a, (usize, Symbol)>,
|
||||||
_data_offset_map: MutMap<Literal<'a>, u32>,
|
_data_offset_map: MutMap<Literal<'a>, u32>,
|
||||||
_data_offset_next: u32,
|
_data_offset_next: u32,
|
||||||
proc_symbols: Vec<'a, Symbol>,
|
proc_symbols: &'a Vec<'a, Symbol>,
|
||||||
code_relocations: Vec<'a, (usize, Symbol)>,
|
|
||||||
|
|
||||||
// Function-level data
|
// Function-level data
|
||||||
code_builder: CodeBuilder<'a>,
|
code_builder: CodeBuilder<'a>,
|
||||||
|
@ -42,7 +42,7 @@ pub struct WasmBackend<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> WasmBackend<'a> {
|
impl<'a> WasmBackend<'a> {
|
||||||
pub fn new(env: &'a Env<'a>, proc_symbols: Vec<'a, Symbol>) -> Self {
|
pub fn new(env: &'a Env<'a>, proc_symbols: &'a Vec<'a, Symbol>) -> Self {
|
||||||
let mut code_section_bytes = std::vec::Vec::with_capacity(4096);
|
let mut code_section_bytes = std::vec::Vec::with_capacity(4096);
|
||||||
|
|
||||||
// Code section header
|
// Code section header
|
||||||
|
@ -58,7 +58,7 @@ impl<'a> WasmBackend<'a> {
|
||||||
_data_offset_map: MutMap::default(),
|
_data_offset_map: MutMap::default(),
|
||||||
_data_offset_next: UNUSED_DATA_SECTION_BYTES,
|
_data_offset_next: UNUSED_DATA_SECTION_BYTES,
|
||||||
proc_symbols,
|
proc_symbols,
|
||||||
code_relocations: Vec::with_capacity_in(256, env.arena),
|
call_relocations: Vec::with_capacity_in(256, env.arena),
|
||||||
|
|
||||||
// Function-level data
|
// Function-level data
|
||||||
block_depth: 0,
|
block_depth: 0,
|
||||||
|
@ -141,7 +141,7 @@ impl<'a> WasmBackend<'a> {
|
||||||
);
|
);
|
||||||
|
|
||||||
let relocs = self.code_builder.serialize(&mut self.code_section_bytes);
|
let relocs = self.code_builder.serialize(&mut self.code_section_bytes);
|
||||||
self.code_relocations.extend(relocs);
|
self.call_relocations.extend(relocs);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,6 @@ use crate::opcodes::*;
|
||||||
use crate::serialize::SerialBuffer;
|
use crate::serialize::SerialBuffer;
|
||||||
use crate::{round_up_to_alignment, LocalId, FRAME_ALIGNMENT_BYTES, STACK_POINTER_GLOBAL_ID};
|
use crate::{round_up_to_alignment, LocalId, FRAME_ALIGNMENT_BYTES, STACK_POINTER_GLOBAL_ID};
|
||||||
|
|
||||||
const DEBUG_LOG: bool = false;
|
|
||||||
|
|
||||||
/// Wasm value type. (Rust representation matches Wasm encoding)
|
/// Wasm value type. (Rust representation matches Wasm encoding)
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||||
|
@ -482,6 +480,7 @@ impl<'a> CodeBuilder<'a> {
|
||||||
pub fn br_if(&mut self, levels: u32) {
|
pub fn br_if(&mut self, levels: u32) {
|
||||||
self.inst_imm32(BRIF, 1, false, levels);
|
self.inst_imm32(BRIF, 1, false, levels);
|
||||||
}
|
}
|
||||||
|
#[allow(dead_code)]
|
||||||
fn br_table() {
|
fn br_table() {
|
||||||
panic!("TODO");
|
panic!("TODO");
|
||||||
}
|
}
|
||||||
|
@ -512,6 +511,8 @@ impl<'a> CodeBuilder<'a> {
|
||||||
self.code.encode_padded_u32(function_index);
|
self.code.encode_padded_u32(function_index);
|
||||||
self.relocations.push((call_offset, function_sym));
|
self.relocations.push((call_offset, function_sym));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
fn call_indirect() {
|
fn call_indirect() {
|
||||||
panic!("Not implemented. Roc doesn't use function pointers");
|
panic!("Not implemented. Roc doesn't use function pointers");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
mod backend;
|
mod backend;
|
||||||
|
pub mod code_builder;
|
||||||
pub mod from_wasm32_memory;
|
pub mod from_wasm32_memory;
|
||||||
mod layout;
|
mod layout;
|
||||||
mod module_builder;
|
pub mod module_builder;
|
||||||
pub mod serialize;
|
pub mod serialize;
|
||||||
mod storage;
|
mod storage;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub mod code_builder;
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
mod opcodes;
|
mod opcodes;
|
||||||
|
|
||||||
|
@ -22,7 +20,10 @@ use roc_mono::layout::LayoutIds;
|
||||||
|
|
||||||
use crate::backend::WasmBackend;
|
use crate::backend::WasmBackend;
|
||||||
use crate::code_builder::{Align, CodeBuilder, ValueType};
|
use crate::code_builder::{Align, CodeBuilder, ValueType};
|
||||||
use crate::serialize::SerialBuffer;
|
use crate::module_builder::{
|
||||||
|
LinkingSection, LinkingSubSection, RelocationEntry, RelocationSection, SectionId, SymInfo,
|
||||||
|
};
|
||||||
|
use crate::serialize::{SerialBuffer, Serialize};
|
||||||
|
|
||||||
const PTR_SIZE: u32 = 4;
|
const PTR_SIZE: u32 = 4;
|
||||||
const PTR_TYPE: ValueType = ValueType::I32;
|
const PTR_TYPE: ValueType = ValueType::I32;
|
||||||
|
@ -61,11 +62,18 @@ pub fn build_module_help<'a>(
|
||||||
procedures: MutMap<(Symbol, ProcLayout<'a>), Proc<'a>>,
|
procedures: MutMap<(Symbol, ProcLayout<'a>), Proc<'a>>,
|
||||||
) -> Result<(builder::ModuleBuilder, std::vec::Vec<u8>), String> {
|
) -> Result<(builder::ModuleBuilder, std::vec::Vec<u8>), String> {
|
||||||
let proc_symbols = Vec::from_iter_in(procedures.keys().map(|(sym, _)| *sym), env.arena);
|
let proc_symbols = Vec::from_iter_in(procedures.keys().map(|(sym, _)| *sym), env.arena);
|
||||||
let mut backend = WasmBackend::new(env, proc_symbols);
|
let mut backend = WasmBackend::new(env, &proc_symbols);
|
||||||
let mut layout_ids = LayoutIds::default();
|
let mut layout_ids = LayoutIds::default();
|
||||||
|
let mut symbol_table_entries = Vec::with_capacity_in(procedures.len(), env.arena);
|
||||||
|
|
||||||
|
for (i, ((sym, layout), proc)) in procedures.into_iter().enumerate() {
|
||||||
|
let proc_name = LayoutIds::default()
|
||||||
|
.get(proc.name, &proc.ret_layout)
|
||||||
|
.to_symbol_string(proc.name, &env.interns);
|
||||||
|
symbol_table_entries.push(SymInfo::for_function(i as u32, proc_name));
|
||||||
|
|
||||||
for ((sym, layout), proc) in procedures.into_iter() {
|
|
||||||
let function_index = backend.build_proc(proc, sym)?;
|
let function_index = backend.build_proc(proc, sym)?;
|
||||||
|
|
||||||
if env.exposed_to_host.contains(&sym) {
|
if env.exposed_to_host.contains(&sym) {
|
||||||
let fn_name = layout_ids
|
let fn_name = layout_ids
|
||||||
.get_toplevel(sym, &layout)
|
.get_toplevel(sym, &layout)
|
||||||
|
@ -86,6 +94,42 @@ pub fn build_module_help<'a>(
|
||||||
.code_section_bytes
|
.code_section_bytes
|
||||||
.overwrite_padded_u32(0, inner_length);
|
.overwrite_padded_u32(0, inner_length);
|
||||||
|
|
||||||
|
// linking metadata section
|
||||||
|
let mut linking_section_bytes = std::vec::Vec::with_capacity(symbol_table_entries.len() * 20);
|
||||||
|
let linking_section = LinkingSection {
|
||||||
|
subsections: bumpalo::vec![in env.arena;
|
||||||
|
LinkingSubSection::SymbolTable(symbol_table_entries)
|
||||||
|
],
|
||||||
|
};
|
||||||
|
linking_section.serialize(&mut linking_section_bytes);
|
||||||
|
backend.module_builder = backend.module_builder.with_section(Section::Unparsed {
|
||||||
|
id: SectionId::Custom as u8,
|
||||||
|
payload: linking_section_bytes,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Code relocations
|
||||||
|
let call_reloc_iter = backend
|
||||||
|
.call_relocations
|
||||||
|
.iter()
|
||||||
|
.map(|(offset, sym)| -> RelocationEntry {
|
||||||
|
let symbol_index = proc_symbols.iter().position(|s| s == sym).unwrap();
|
||||||
|
RelocationEntry::for_function_call(*offset as u32, symbol_index as u32)
|
||||||
|
});
|
||||||
|
|
||||||
|
let code_reloc_section = RelocationSection {
|
||||||
|
name: "reloc.CODE".to_string(),
|
||||||
|
entries: Vec::from_iter_in(call_reloc_iter, env.arena),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut code_reloc_section_bytes = std::vec::Vec::with_capacity(256);
|
||||||
|
code_reloc_section.serialize(&mut code_reloc_section_bytes);
|
||||||
|
|
||||||
|
// Must come after linking section
|
||||||
|
backend.module_builder = backend.module_builder.with_section(Section::Unparsed {
|
||||||
|
id: SectionId::Custom as u8,
|
||||||
|
payload: code_reloc_section_bytes,
|
||||||
|
});
|
||||||
|
|
||||||
const MIN_MEMORY_SIZE_KB: u32 = 1024;
|
const MIN_MEMORY_SIZE_KB: u32 = 1024;
|
||||||
const PAGE_SIZE_KB: u32 = 64;
|
const PAGE_SIZE_KB: u32 = 64;
|
||||||
|
|
||||||
|
@ -122,7 +166,7 @@ pub fn replace_code_section(module: &mut Module, code_section_bytes: std::vec::V
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
sections[code_section_index] = Section::Unparsed {
|
sections[code_section_index] = Section::Unparsed {
|
||||||
id: CODE_SECTION_ID,
|
id: SectionId::Code as u8,
|
||||||
payload: code_section_bytes,
|
payload: code_section_bytes,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use bumpalo::collections::vec::Vec;
|
use bumpalo::collections::vec::Vec;
|
||||||
use roc_module::symbol::{Interns, Symbol};
|
|
||||||
|
|
||||||
use crate::code_builder::Align;
|
use crate::code_builder::Align;
|
||||||
use crate::serialize::{SerialBuffer, Serialize};
|
use crate::serialize::{SerialBuffer, Serialize};
|
||||||
|
@ -39,11 +38,11 @@ fn _write_section_header<T: SerialBuffer>(buffer: &mut T, id: SectionId) -> Sect
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write a custom section header, returning the position of the encoded length
|
/// Write a custom section header, returning the position of the encoded length
|
||||||
fn write_custom_section_header<'s, T: SerialBuffer>(
|
fn write_custom_section_header<T: SerialBuffer>(
|
||||||
buffer: &mut T,
|
buffer: &mut T,
|
||||||
name: &'s str,
|
name: &str,
|
||||||
) -> SectionHeaderIndices {
|
) -> SectionHeaderIndices {
|
||||||
buffer.append_byte(SectionId::Custom as u8);
|
// buffer.append_byte(SectionId::Custom as u8); // TODO: uncomment when we get rid of parity_wasm
|
||||||
let size_index = buffer.reserve_padded_u32();
|
let size_index = buffer.reserve_padded_u32();
|
||||||
let body_index = buffer.size();
|
let body_index = buffer.size();
|
||||||
buffer.append_slice(name.as_bytes());
|
buffer.append_slice(name.as_bytes());
|
||||||
|
@ -59,7 +58,7 @@ fn update_section_size<T: SerialBuffer>(buffer: &mut T, header_indices: SectionH
|
||||||
buffer.overwrite_padded_u32(header_indices.size_index, size as u32);
|
buffer.overwrite_padded_u32(header_indices.size_index, size as u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_vector_with_count<'bump, SB, S>(buffer: &mut SB, items: &Vec<'bump, S>)
|
fn serialize_vector_with_count<'a, SB, S>(buffer: &mut SB, items: &Vec<'a, S>)
|
||||||
where
|
where
|
||||||
SB: SerialBuffer,
|
SB: SerialBuffer,
|
||||||
S: Serialize,
|
S: Serialize,
|
||||||
|
@ -147,6 +146,16 @@ pub enum RelocationEntry {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl RelocationEntry {
|
||||||
|
pub fn for_function_call(offset: u32, symbol_index: u32) -> Self {
|
||||||
|
RelocationEntry::Index {
|
||||||
|
type_id: IndexRelocType::FunctionIndexLeb,
|
||||||
|
offset,
|
||||||
|
symbol_index,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Serialize for RelocationEntry {
|
impl Serialize for RelocationEntry {
|
||||||
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
||||||
match self {
|
match self {
|
||||||
|
@ -174,14 +183,14 @@ impl Serialize for RelocationEntry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RelocationSection<'s, 'bump> {
|
pub struct RelocationSection<'a> {
|
||||||
name: &'s str,
|
pub name: String,
|
||||||
entries: Vec<'bump, RelocationEntry>,
|
pub entries: Vec<'a, RelocationEntry>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'s, 'bump> Serialize for RelocationSection<'s, 'bump> {
|
impl<'a> Serialize for RelocationSection<'a> {
|
||||||
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
||||||
let header_indices = write_custom_section_header(buffer, self.name);
|
let header_indices = write_custom_section_header(buffer, &self.name);
|
||||||
for entry in self.entries.iter() {
|
for entry in self.entries.iter() {
|
||||||
entry.serialize(buffer);
|
entry.serialize(buffer);
|
||||||
}
|
}
|
||||||
|
@ -198,24 +207,24 @@ impl<'s, 'bump> Serialize for RelocationSection<'s, 'bump> {
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
|
|
||||||
/// Linking metadata for data segments
|
/// Linking metadata for data segments
|
||||||
pub struct LinkingSegment<'s> {
|
pub struct LinkingSegment {
|
||||||
name: &'s str,
|
pub name: String,
|
||||||
alignment: Align,
|
pub alignment: Align,
|
||||||
flags: u32,
|
pub flags: u32,
|
||||||
}
|
}
|
||||||
impl<'s> Serialize for LinkingSegment<'s> {
|
impl Serialize for LinkingSegment {
|
||||||
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
fn serialize<T: SerialBuffer>(&self, _buffer: &mut T) {
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Linking metadata for init (start) functions
|
/// Linking metadata for init (start) functions
|
||||||
pub struct LinkingInitFunc {
|
pub struct LinkingInitFunc {
|
||||||
priority: u32,
|
pub priority: u32,
|
||||||
symbol_index: u32, // index in the symbol table, not the function index
|
pub symbol_index: u32, // index in the symbol table, not the function index
|
||||||
}
|
}
|
||||||
impl Serialize for LinkingInitFunc {
|
impl Serialize for LinkingInitFunc {
|
||||||
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
fn serialize<T: SerialBuffer>(&self, _buffer: &mut T) {
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,11 +247,11 @@ pub enum ComdatSymKind {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ComdatSym {
|
pub struct ComdatSym {
|
||||||
kind: ComdatSymKind,
|
pub kind: ComdatSymKind,
|
||||||
index: u32,
|
pub index: u32,
|
||||||
}
|
}
|
||||||
impl Serialize for ComdatSym {
|
impl Serialize for ComdatSym {
|
||||||
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
fn serialize<T: SerialBuffer>(&self, _buffer: &mut T) {
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -251,13 +260,14 @@ impl Serialize for ComdatSym {
|
||||||
/// A COMDAT group may contain one or more functions, data segments, and/or custom sections.
|
/// A COMDAT group may contain one or more functions, data segments, and/or custom sections.
|
||||||
/// The linker will include all of these elements with a given group name from one object file,
|
/// The linker will include all of these elements with a given group name from one object file,
|
||||||
/// and will exclude any element with this group name from all other object files.
|
/// and will exclude any element with this group name from all other object files.
|
||||||
pub struct LinkingComdat<'s, 'bump> {
|
#[allow(dead_code)]
|
||||||
name: &'s str,
|
pub struct LinkingComdat<'a> {
|
||||||
|
name: String,
|
||||||
flags: u32,
|
flags: u32,
|
||||||
syms: Vec<'bump, ComdatSym>,
|
syms: Vec<'a, ComdatSym>,
|
||||||
}
|
}
|
||||||
impl<'s, 'bump> Serialize for LinkingComdat<'s, 'bump> {
|
impl<'a> Serialize for LinkingComdat<'a> {
|
||||||
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
fn serialize<T: SerialBuffer>(&self, _buffer: &mut T) {
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -306,11 +316,11 @@ pub const WASM_SYM_EXPLICIT_NAME: u32 = 0x40; // use the name from the symbol ta
|
||||||
/// linker output, regardless of whether it is used by the program.
|
/// linker output, regardless of whether it is used by the program.
|
||||||
pub const WASM_SYM_NO_STRIP: u32 = 0x80;
|
pub const WASM_SYM_NO_STRIP: u32 = 0x80;
|
||||||
|
|
||||||
pub enum WasmObjectSymbol<'s> {
|
pub enum WasmObjectSymbol {
|
||||||
Defined { index: u32, name: &'s str },
|
Defined { index: u32, name: String },
|
||||||
Imported { index: u32 },
|
Imported { index: u32 },
|
||||||
}
|
}
|
||||||
impl<'s> Serialize for WasmObjectSymbol<'s> {
|
impl Serialize for WasmObjectSymbol {
|
||||||
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
||||||
match self {
|
match self {
|
||||||
Self::Defined { index, name } => {
|
Self::Defined { index, name } => {
|
||||||
|
@ -325,18 +335,18 @@ impl<'s> Serialize for WasmObjectSymbol<'s> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum DataSymbol<'s> {
|
pub enum DataSymbol {
|
||||||
Defined {
|
Defined {
|
||||||
name: &'s str,
|
name: String,
|
||||||
index: u32,
|
index: u32,
|
||||||
offset: u32,
|
offset: u32,
|
||||||
size: u32,
|
size: u32,
|
||||||
},
|
},
|
||||||
Imported {
|
Imported {
|
||||||
name: &'s str,
|
name: String,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
impl<'s> Serialize for DataSymbol<'s> {
|
impl Serialize for DataSymbol {
|
||||||
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
||||||
match self {
|
match self {
|
||||||
Self::Defined {
|
Self::Defined {
|
||||||
|
@ -363,20 +373,33 @@ impl<'s> Serialize for DataSymbol<'s> {
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct SectionIndex(u32);
|
pub struct SectionIndex(u32);
|
||||||
|
|
||||||
pub enum SymInfoFields<'s> {
|
pub enum SymInfoFields {
|
||||||
Function(WasmObjectSymbol<'s>),
|
Function(WasmObjectSymbol),
|
||||||
Data(DataSymbol<'s>),
|
Data(DataSymbol),
|
||||||
Global(WasmObjectSymbol<'s>),
|
Global(WasmObjectSymbol),
|
||||||
Section(SectionIndex),
|
Section(SectionIndex),
|
||||||
Event(WasmObjectSymbol<'s>),
|
Event(WasmObjectSymbol),
|
||||||
Table(WasmObjectSymbol<'s>),
|
Table(WasmObjectSymbol),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SymInfo<'s> {
|
pub struct SymInfo {
|
||||||
flags: u32,
|
flags: u32,
|
||||||
info: SymInfoFields<'s>,
|
info: SymInfoFields,
|
||||||
}
|
}
|
||||||
impl<'s> Serialize for SymInfo<'s> {
|
impl SymInfo {
|
||||||
|
pub fn for_function(wasm_function_index: u32, name: String) -> Self {
|
||||||
|
let linking_symbol = WasmObjectSymbol::Defined {
|
||||||
|
index: wasm_function_index,
|
||||||
|
name,
|
||||||
|
};
|
||||||
|
SymInfo {
|
||||||
|
flags: 0,
|
||||||
|
info: SymInfoFields::Function(linking_symbol),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serialize for SymInfo {
|
||||||
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
||||||
buffer.append_byte(match self.info {
|
buffer.append_byte(match self.info {
|
||||||
SymInfoFields::Function(_) => 0,
|
SymInfoFields::Function(_) => 0,
|
||||||
|
@ -406,18 +429,18 @@ impl<'s> Serialize for SymInfo<'s> {
|
||||||
//
|
//
|
||||||
//--------------------------------
|
//--------------------------------
|
||||||
|
|
||||||
pub enum LinkingSubSection<'s, 'bump> {
|
pub enum LinkingSubSection<'a> {
|
||||||
/// Extra metadata about the data segments.
|
/// Extra metadata about the data segments.
|
||||||
SegmentInfo(Vec<'bump, LinkingSegment<'s>>),
|
SegmentInfo(Vec<'a, LinkingSegment>),
|
||||||
/// Specifies a list of constructor functions to be called at startup.
|
/// Specifies a list of constructor functions to be called at startup.
|
||||||
/// These constructors will be called in priority order after memory has been initialized.
|
/// These constructors will be called in priority order after memory has been initialized.
|
||||||
InitFuncs(Vec<'bump, LinkingInitFunc>),
|
InitFuncs(Vec<'a, LinkingInitFunc>),
|
||||||
/// Specifies the COMDAT groups of associated linking objects, which are linked only once and all together.
|
/// Specifies the COMDAT groups of associated linking objects, which are linked only once and all together.
|
||||||
ComdatInfo(Vec<'bump, LinkingComdat<'s, 'bump>>),
|
ComdatInfo(Vec<'a, LinkingComdat<'a>>),
|
||||||
/// Specifies extra information about the symbols present in the module.
|
/// Specifies extra information about the symbols present in the module.
|
||||||
SymbolTable(Vec<'bump, SymInfo<'s>>),
|
SymbolTable(Vec<'a, SymInfo>),
|
||||||
}
|
}
|
||||||
impl<'s, 'bump> Serialize for LinkingSubSection<'s, 'bump> {
|
impl<'a> Serialize for LinkingSubSection<'a> {
|
||||||
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
||||||
buffer.append_byte(match self {
|
buffer.append_byte(match self {
|
||||||
Self::SegmentInfo(_) => 5,
|
Self::SegmentInfo(_) => 5,
|
||||||
|
@ -442,10 +465,10 @@ impl<'s, 'bump> Serialize for LinkingSubSection<'s, 'bump> {
|
||||||
|
|
||||||
const LINKING_VERSION: u8 = 2;
|
const LINKING_VERSION: u8 = 2;
|
||||||
|
|
||||||
pub struct LinkingSection<'s, 'bump> {
|
pub struct LinkingSection<'a> {
|
||||||
subsections: Vec<'bump, LinkingSubSection<'s, 'bump>>,
|
pub subsections: Vec<'a, LinkingSubSection<'a>>,
|
||||||
}
|
}
|
||||||
impl<'s, 'bump> Serialize for LinkingSection<'s, 'bump> {
|
impl<'a> Serialize for LinkingSection<'a> {
|
||||||
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
fn serialize<T: SerialBuffer>(&self, buffer: &mut T) {
|
||||||
let header_indices = write_custom_section_header(buffer, "linking");
|
let header_indices = write_custom_section_header(buffer, "linking");
|
||||||
buffer.append_byte(LINKING_VERSION);
|
buffer.append_byte(LINKING_VERSION);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue