mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-12 05:18:43 +00:00
Merge .eh_frame without interpretation. Add a 0-CIE to the end.
Add unfinished attempt at using gimli, to be deleted but recorded in case we need it in the future.
This commit is contained in:
@@ -6,8 +6,11 @@ use wasm_common::entity::{EntityRef, PrimaryMap, SecondaryMap};
|
||||
use wasm_common::LocalFunctionIndex;
|
||||
use wasmer_compiler::{
|
||||
Compilation, CompileError, CompileModuleInfo, Compiler, FunctionBodyData,
|
||||
ModuleTranslationState, RelocationTarget, SectionIndex, Target,
|
||||
ModuleTranslationState, RelocationTarget, SectionIndex, Target, CustomSection,
|
||||
SectionBody, CustomSectionProtection, Dwarf,
|
||||
};
|
||||
use wasmer_runtime::{MemoryPlan, ModuleInfo, TablePlan};
|
||||
//use gimli::read::UnwindSection;
|
||||
|
||||
//use std::sync::{Arc, Mutex};
|
||||
|
||||
@@ -31,6 +34,17 @@ impl LLVMCompiler {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
fn cie_to_cie(read_cie: gimli::read::CommonInformationEntry) -> gimli::write::CommonInformationEntry {
|
||||
|
||||
}
|
||||
|
||||
fn fde_to_fde(read_fde: gimli::read::FrameDescriptionEntry) -> gimli::write::FrameDescriptionEntry {
|
||||
let mut write_fde = gimli::write::FrameDescriptionEntry::new(?, read_fde.len())
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
impl Compiler for LLVMCompiler {
|
||||
/// Compile the module using LLVM, producing a compilation result with
|
||||
/// associated relocations.
|
||||
@@ -57,6 +71,9 @@ impl Compiler for LLVMCompiler {
|
||||
.unwrap_or_else(|| format!("fn{}", func_index.index()));
|
||||
}
|
||||
let mut module_custom_sections = PrimaryMap::new();
|
||||
//let mut frame_table = gimli::write::FrameTable::default();
|
||||
let mut frame_section_bytes = vec![];
|
||||
let mut frame_section_relocations = vec![];
|
||||
let functions = function_body_inputs
|
||||
.into_iter()
|
||||
.collect::<Vec<(LocalFunctionIndex, &FunctionBodyData<'_>)>>()
|
||||
@@ -83,9 +100,9 @@ impl Compiler for LLVMCompiler {
|
||||
)
|
||||
.collect::<Result<Vec<_>, CompileError>>()?
|
||||
.into_iter()
|
||||
.map(|(mut compiled_function, function_custom_sections, _eh_frame_section_indices)| {
|
||||
.map(|(mut compiled_function, function_custom_sections, eh_frame_section_indices)| {
|
||||
let first_section = module_custom_sections.len() as u32;
|
||||
for (_, custom_section) in function_custom_sections.iter() {
|
||||
for (section_index, custom_section) in function_custom_sections.iter() {
|
||||
// TODO: remove this call to clone()
|
||||
let mut custom_section = custom_section.clone();
|
||||
for mut reloc in &mut custom_section.relocations {
|
||||
@@ -95,7 +112,42 @@ impl Compiler for LLVMCompiler {
|
||||
)
|
||||
}
|
||||
}
|
||||
module_custom_sections.push(custom_section);
|
||||
if eh_frame_section_indices.contains(§ion_index) {
|
||||
// TODO: pull endianness out of target
|
||||
/*
|
||||
let eh_frame = gimli::read::EhFrame::new(custom_section.bytes.as_slice(), gimli::NativeEndian);
|
||||
let base_addresses = gimli::read::BaseAddresses::default();
|
||||
let mut entries = eh_frame.entries(&base_addresses);
|
||||
let mut current_cie = None;
|
||||
while let Some(entry) = entries.next().unwrap() {
|
||||
match entry {
|
||||
gimli::CieOrFde::Cie(cie) => {
|
||||
current_cie = Some(cie);
|
||||
frame_table.add_cie(cie.into());
|
||||
},
|
||||
gimli::CieOrFde::Fde(partial_fde) => {
|
||||
// TODO: unwrap safety
|
||||
let fde = partial_fde.parse(current_cie.unwrap()).unwrap();
|
||||
frame_table.add_fde(current_cie.unwrap().into(), fde.into());
|
||||
}
|
||||
};
|
||||
}
|
||||
*/
|
||||
let offset = frame_section_bytes.len() as u32;
|
||||
for mut reloc in &mut custom_section.relocations {
|
||||
reloc.offset += offset;
|
||||
}
|
||||
frame_section_bytes.extend_from_slice(custom_section.bytes.as_slice());
|
||||
frame_section_relocations.extend(custom_section.relocations);
|
||||
// TODO: we do this to keep the count right, remove it.
|
||||
module_custom_sections.push(CustomSection {
|
||||
protection: CustomSectionProtection::Read,
|
||||
bytes: SectionBody::new_with_vec(vec![]),
|
||||
relocations: vec![]
|
||||
});
|
||||
} else {
|
||||
module_custom_sections.push(custom_section);
|
||||
}
|
||||
}
|
||||
for mut reloc in &mut compiled_function.relocations {
|
||||
if let RelocationTarget::CustomSection(index) = reloc.reloc_target {
|
||||
@@ -108,6 +160,30 @@ impl Compiler for LLVMCompiler {
|
||||
})
|
||||
.collect::<PrimaryMap<LocalFunctionIndex, _>>();
|
||||
|
||||
let dwarf = if !frame_section_bytes.is_empty() {
|
||||
let dwarf = Some(Dwarf::new(SectionIndex::from_u32(module_custom_sections.len() as u32)));
|
||||
// Terminator CIE.
|
||||
frame_section_bytes.extend(vec!
|
||||
[0x00, 0x00, 0x00, 0x00, // Length
|
||||
0x00, 0x00, 0x00, 0x00, // CIE ID
|
||||
0x10, // Version (must be 1)
|
||||
0x00, // Augmentation data
|
||||
0x00, 0x00,
|
||||
0xa4, 0x2e, 0x00, 0x00,
|
||||
0x30, 0x73, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00]);
|
||||
module_custom_sections.push(CustomSection {
|
||||
protection: CustomSectionProtection::Read,
|
||||
bytes: SectionBody::new_with_vec(frame_section_bytes),
|
||||
relocations: frame_section_relocations
|
||||
});
|
||||
dwarf
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let function_call_trampolines = module
|
||||
.signatures
|
||||
.values()
|
||||
@@ -146,7 +222,7 @@ impl Compiler for LLVMCompiler {
|
||||
module_custom_sections,
|
||||
function_call_trampolines,
|
||||
dynamic_function_trampolines,
|
||||
None,
|
||||
dwarf,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,15 +146,17 @@ where
|
||||
// Also add any .eh_frame sections.
|
||||
let mut eh_frame_section_indices = vec![];
|
||||
// TODO: this constant has been added to goblin, now waiting for release
|
||||
const SHT_X86_64_UNWIND: u64 = 0x7000_0001;
|
||||
const SHT_X86_64_UNWIND: u32 = 0x7000_0001;
|
||||
for (index, shdr) in elf.section_headers.iter().enumerate() {
|
||||
if shdr.sh_flags & SHT_X86_64_UNWIND != 0 {
|
||||
if shdr.sh_type == SHT_X86_64_UNWIND {
|
||||
let index = ElfSectionIndex::from_usize(index)?;
|
||||
worklist.push(index);
|
||||
visited.insert(index);
|
||||
eh_frame_section_indices.push(index);
|
||||
// This allocates a custom section index for the ELF section.
|
||||
elf_section_to_target(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while let Some(section_index) = worklist.pop() {
|
||||
for reloc in reloc_sections
|
||||
@@ -166,6 +168,7 @@ where
|
||||
// TODO: these constants are not per-arch, we'll need to
|
||||
// make the whole match per-arch.
|
||||
goblin::elf::reloc::R_X86_64_64 => RelocationKind::Abs8,
|
||||
goblin::elf::reloc::R_X86_64_PC64 => RelocationKind::X86PCRel8,
|
||||
goblin::elf::reloc::R_X86_64_GOT64 => {
|
||||
return Err(CompileError::Codegen(
|
||||
"unimplemented PIC relocation R_X86_64_GOT64".into(),
|
||||
@@ -234,6 +237,21 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
let eh_frame_section_indices = eh_frame_section_indices
|
||||
.iter()
|
||||
.map(|index| {
|
||||
section_to_custom_section.get(index).map_or_else(
|
||||
|| {
|
||||
Err(CompileError::Codegen(format!(
|
||||
".eh_frame section with index={:?} was never loaded",
|
||||
index
|
||||
)))
|
||||
},
|
||||
|idx| Ok(*idx),
|
||||
)
|
||||
})
|
||||
.collect::<Result<Vec<SectionIndex>, _>>()?;
|
||||
|
||||
let mut custom_sections = section_to_custom_section
|
||||
.iter()
|
||||
.map(|(elf_section_index, custom_section_index)| {
|
||||
@@ -255,8 +273,6 @@ where
|
||||
.map(|(_, v)| v)
|
||||
.collect::<PrimaryMap<SectionIndex, _>>();
|
||||
|
||||
let eh_frame_section_indices = eh_frame_section_indices.iter().map(|index| section_to_custom_section.get(index).map_or_else(|| Err(CompileError::Codegen(format!(".eh_frame section with index={:?} was never loaded", index))), |idx| Ok(*idx))).collect::<Result<Vec<SectionIndex>, _>>()?;
|
||||
|
||||
let function_body = FunctionBody {
|
||||
body: section_bytes(root_section_index),
|
||||
unwind_info: None,
|
||||
|
||||
@@ -94,18 +94,20 @@ impl FuncTrampoline {
|
||||
}
|
||||
|
||||
let mem_buf_slice = memory_buffer.as_slice();
|
||||
let (function, sections, _eh_frame_section_indices) =
|
||||
let (function, _sections, _eh_frame_section_indices) =
|
||||
load_object_file(mem_buf_slice, FUNCTION_SECTION, None, |name: &String| {
|
||||
Err(CompileError::Codegen(format!(
|
||||
"trampoline generation produced reference to unknown function {}",
|
||||
name
|
||||
)))
|
||||
})?;
|
||||
/*
|
||||
if !sections.is_empty() {
|
||||
return Err(CompileError::Codegen(
|
||||
"trampoline generation produced custom sections".into(),
|
||||
));
|
||||
}
|
||||
*/
|
||||
if !function.relocations.is_empty() {
|
||||
return Err(CompileError::Codegen(
|
||||
"trampoline generation produced relocations".into(),
|
||||
@@ -175,18 +177,20 @@ impl FuncTrampoline {
|
||||
}
|
||||
|
||||
let mem_buf_slice = memory_buffer.as_slice();
|
||||
let (function, sections, _eh_frame_section_indices) =
|
||||
let (function, _sections, _eh_frame_section_indices) =
|
||||
load_object_file(mem_buf_slice, FUNCTION_SECTION, None, |name: &String| {
|
||||
Err(CompileError::Codegen(format!(
|
||||
"trampoline generation produced reference to unknown function {}",
|
||||
name
|
||||
)))
|
||||
})?;
|
||||
/*
|
||||
if !sections.is_empty() {
|
||||
return Err(CompileError::Codegen(
|
||||
"trampoline generation produced custom sections".into(),
|
||||
));
|
||||
}
|
||||
*/
|
||||
if !function.relocations.is_empty() {
|
||||
return Err(CompileError::Codegen(
|
||||
"trampoline generation produced relocations".into(),
|
||||
|
||||
Reference in New Issue
Block a user