]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_codegen_cranelift/src/debuginfo/object.rs
Rollup merge of #93080 - SkiFire13:itermut-as_mut_slice, r=m-ou-se
[rust.git] / compiler / rustc_codegen_cranelift / src / debuginfo / object.rs
1 use rustc_data_structures::fx::FxHashMap;
2
3 use cranelift_module::FuncId;
4 use cranelift_object::ObjectProduct;
5
6 use object::write::{Relocation, StandardSegment};
7 use object::{RelocationEncoding, SectionKind};
8
9 use gimli::SectionId;
10
11 use crate::debuginfo::{DebugReloc, DebugRelocName};
12
13 pub(super) trait WriteDebugInfo {
14     type SectionId: Copy;
15
16     fn add_debug_section(&mut self, name: SectionId, data: Vec<u8>) -> Self::SectionId;
17     fn add_debug_reloc(
18         &mut self,
19         section_map: &FxHashMap<SectionId, Self::SectionId>,
20         from: &Self::SectionId,
21         reloc: &DebugReloc,
22     );
23 }
24
25 impl WriteDebugInfo for ObjectProduct {
26     type SectionId = (object::write::SectionId, object::write::SymbolId);
27
28     fn add_debug_section(
29         &mut self,
30         id: SectionId,
31         data: Vec<u8>,
32     ) -> (object::write::SectionId, object::write::SymbolId) {
33         let name = if self.object.format() == object::BinaryFormat::MachO {
34             id.name().replace('.', "__") // machO expects __debug_info instead of .debug_info
35         } else {
36             id.name().to_string()
37         }
38         .into_bytes();
39
40         let segment = self.object.segment_name(StandardSegment::Debug).to_vec();
41         // FIXME use SHT_X86_64_UNWIND for .eh_frame
42         let section_id = self.object.add_section(
43             segment,
44             name,
45             if id == SectionId::EhFrame { SectionKind::ReadOnlyData } else { SectionKind::Debug },
46         );
47         self.object
48             .section_mut(section_id)
49             .set_data(data, if id == SectionId::EhFrame { 8 } else { 1 });
50         let symbol_id = self.object.section_symbol(section_id);
51         (section_id, symbol_id)
52     }
53
54     fn add_debug_reloc(
55         &mut self,
56         section_map: &FxHashMap<SectionId, Self::SectionId>,
57         from: &Self::SectionId,
58         reloc: &DebugReloc,
59     ) {
60         let (symbol, symbol_offset) = match reloc.name {
61             DebugRelocName::Section(id) => (section_map.get(&id).unwrap().1, 0),
62             DebugRelocName::Symbol(id) => {
63                 let symbol_id = self.function_symbol(FuncId::from_u32(id.try_into().unwrap()));
64                 self.object
65                     .symbol_section_and_offset(symbol_id)
66                     .expect("Debug reloc for undef sym???")
67             }
68         };
69         self.object
70             .add_relocation(
71                 from.0,
72                 Relocation {
73                     offset: u64::from(reloc.offset),
74                     symbol,
75                     kind: reloc.kind,
76                     encoding: RelocationEncoding::Generic,
77                     size: reloc.size * 8,
78                     addend: i64::try_from(symbol_offset).unwrap() + reloc.addend,
79                 },
80             )
81             .unwrap();
82     }
83 }