wasmer_compiler_cranelift/
dwarf.rs1use gimli::write::{Address, EndianVec, Result, Writer};
2use gimli::{RunTimeEndian, SectionId};
3use wasmer_compiler::types::{
4 relocation::{Relocation, RelocationKind, RelocationTarget},
5 section::{CustomSection, CustomSectionProtection, SectionBody},
6};
7use wasmer_types::{LocalFunctionIndex, entity::EntityRef, target::Endianness};
8
9#[derive(Clone, Debug)]
10pub struct WriterRelocate {
11 pub relocs: Vec<Relocation>,
12 writer: EndianVec<RunTimeEndian>,
13}
14
15impl WriterRelocate {
16 pub const FUNCTION_SYMBOL: usize = 0;
17 pub fn new(endianness: Option<Endianness>) -> Self {
18 let endianness = match endianness {
19 Some(Endianness::Little) => RunTimeEndian::Little,
20 Some(Endianness::Big) => RunTimeEndian::Big,
21 None => RunTimeEndian::default(),
23 };
24 Self {
25 relocs: Vec::new(),
26 writer: EndianVec::new(endianness),
27 }
28 }
29
30 pub fn into_section(mut self) -> CustomSection {
31 self.writer.write_u32(0).unwrap();
33 let data = self.writer.into_vec();
34 CustomSection {
35 protection: CustomSectionProtection::Read,
36 alignment: None,
37 bytes: SectionBody::new_with_vec(data),
38 relocations: self.relocs,
39 }
40 }
41}
42
43impl Writer for WriterRelocate {
44 type Endian = RunTimeEndian;
45
46 fn endian(&self) -> Self::Endian {
47 self.writer.endian()
48 }
49
50 fn len(&self) -> usize {
51 self.writer.len()
52 }
53
54 fn write(&mut self, bytes: &[u8]) -> Result<()> {
55 self.writer.write(bytes)
56 }
57
58 fn write_at(&mut self, offset: usize, bytes: &[u8]) -> Result<()> {
59 self.writer.write_at(offset, bytes)
60 }
61
62 fn write_address(&mut self, address: Address, size: u8) -> Result<()> {
63 match address {
64 Address::Constant(val) => self.write_udata(val, size),
65 Address::Symbol { symbol, addend } => {
66 if symbol == Self::FUNCTION_SYMBOL {
68 let function_index = LocalFunctionIndex::new(addend as _);
70 let reloc_target = RelocationTarget::LocalFunc(function_index);
71 let offset = self.len() as u32;
72 let kind = match size {
73 8 => RelocationKind::Abs8,
74 _ => unimplemented!("dwarf relocation size not yet supported: {}", size),
75 };
76 let addend = 0;
77 self.relocs.push(Relocation {
78 kind,
79 reloc_target,
80 offset,
81 addend,
82 });
83 self.write_udata(addend as _, size)
84 } else {
85 unreachable!("Symbol {} in DWARF not recognized", symbol);
86 }
87 }
88 }
89 }
90
91 fn write_offset(&mut self, _val: usize, _section: SectionId, _size: u8) -> Result<()> {
92 unimplemented!("write_offset not yet implemented");
93 }
94
95 fn write_offset_at(
96 &mut self,
97 _offset: usize,
98 _val: usize,
99 _section: SectionId,
100 _size: u8,
101 ) -> Result<()> {
102 unimplemented!("write_offset_at not yet implemented");
103 }
104}