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