Skip to content

Commit 478da67

Browse files
committed
Make debuginfo writing backend agnostic
1 parent f0dde6c commit 478da67

File tree

4 files changed

+126
-47
lines changed

4 files changed

+126
-47
lines changed

src/backend.rs

+104-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,21 @@
1-
pub trait Product {
1+
use std::collections::HashMap;
2+
3+
use cranelift_module::FuncId;
4+
5+
use faerie::*;
6+
use object::{SectionKind, RelocationKind, RelocationEncoding};
7+
use object::write::*;
8+
use cranelift_object::*;
9+
10+
use gimli::SectionId;
11+
12+
use crate::debuginfo::{DebugReloc, DebugRelocName};
13+
14+
pub trait WriteMetadata {
215
fn add_rustc_section(&mut self, symbol_name: String, data: Vec<u8>, is_like_osx: bool);
316
}
417

5-
impl Product for faerie::Artifact {
18+
impl WriteMetadata for faerie::Artifact {
619
fn add_rustc_section(&mut self, symbol_name: String, data: Vec<u8>, is_like_osx: bool) {
720
self
821
.declare(".rustc", faerie::Decl::section(faerie::SectionKind::Data))
@@ -25,7 +38,7 @@ impl Product for faerie::Artifact {
2538
}
2639
}
2740

28-
impl Product for object::write::Object {
41+
impl WriteMetadata for object::write::Object {
2942
fn add_rustc_section(&mut self, symbol_name: String, data: Vec<u8>, is_like_osx: bool) {
3043
let segment = self.segment_name(object::write::StandardSegment::Data).to_vec();
3144
let section_id = self.add_section(segment, b".rustc".to_vec(), object::SectionKind::Data);
@@ -46,3 +59,91 @@ impl Product for object::write::Object {
4659
}
4760
}
4861
}
62+
63+
pub trait WriteDebugInfo {
64+
type SectionId;
65+
66+
fn add_debug_section(&mut self, name: SectionId, data: Vec<u8>) -> Self::SectionId;
67+
fn add_debug_reloc(
68+
&mut self,
69+
section_map: &HashMap<SectionId, Self::SectionId>,
70+
symbol_map: &indexmap::IndexSet<(String, FuncId)>,
71+
from: &Self::SectionId,
72+
reloc: &DebugReloc,
73+
);
74+
}
75+
76+
impl WriteDebugInfo for Artifact {
77+
type SectionId = SectionId;
78+
79+
fn add_debug_section(&mut self, id: SectionId, data: Vec<u8>) -> SectionId {
80+
self.declare_with(id.name(), Decl::section(faerie::SectionKind::Debug), data).unwrap();
81+
id
82+
}
83+
84+
fn add_debug_reloc(
85+
&mut self,
86+
_section_map: &HashMap<SectionId, Self::SectionId>,
87+
symbol_map: &indexmap::IndexSet<(String, FuncId)>,
88+
from: &Self::SectionId,
89+
reloc: &DebugReloc,
90+
) {
91+
self
92+
.link_with(
93+
faerie::Link {
94+
from: from.name(),
95+
to: match reloc.name {
96+
DebugRelocName::Section(id) => id.name(),
97+
DebugRelocName::Symbol(index) => &symbol_map.get_index(index).unwrap().0,
98+
},
99+
at: u64::from(reloc.offset),
100+
},
101+
faerie::Reloc::Debug {
102+
size: reloc.size,
103+
addend: reloc.addend as i32,
104+
},
105+
)
106+
.expect("faerie relocation error");
107+
}
108+
}
109+
110+
impl WriteDebugInfo for ObjectProduct {
111+
type SectionId = (object::write::SectionId, object::write::SymbolId);
112+
113+
fn add_debug_section(
114+
&mut self,
115+
id: SectionId,
116+
data: Vec<u8>,
117+
) -> (object::write::SectionId, object::write::SymbolId) {
118+
let segment = self.object.segment_name(StandardSegment::Debug).to_vec();
119+
let name = id.name().as_bytes().to_vec();
120+
let section_id = self.object.add_section(segment, name, SectionKind::Debug);
121+
self.object.section_mut(section_id).set_data(data, 1);
122+
let symbol_id = self.object.section_symbol(section_id);
123+
(section_id, symbol_id)
124+
}
125+
126+
fn add_debug_reloc(
127+
&mut self,
128+
section_map: &HashMap<SectionId, Self::SectionId>,
129+
symbol_map: &indexmap::IndexSet<(String, FuncId)>,
130+
from: &Self::SectionId,
131+
reloc: &DebugReloc,
132+
) {
133+
let symbol = match reloc.name {
134+
DebugRelocName::Section(id) => section_map.get(&id).unwrap().1,
135+
DebugRelocName::Symbol(id) => {
136+
let (_func_name, func_id) = symbol_map.get_index(id).unwrap();
137+
self.function_symbol(*func_id)
138+
}
139+
};
140+
self.object.add_relocation(from.0, Relocation {
141+
offset: u64::from(reloc.offset),
142+
symbol,
143+
kind: RelocationKind::Absolute,
144+
encoding: RelocationEncoding::Generic,
145+
size: reloc.size * 8,
146+
addend: reloc.addend,
147+
}).unwrap();
148+
}
149+
}

src/base.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub fn trans_fn<'clif, 'tcx, B: Backend + 'static>(
1717
let mut debug_context = cx
1818
.debug_context
1919
.as_mut()
20-
.map(|debug_context| FunctionDebugContext::new(tcx, debug_context, mir, &name, &sig));
20+
.map(|debug_context| FunctionDebugContext::new(tcx, debug_context, mir, func_id, &name, &sig));
2121

2222
// Make FunctionBuilder
2323
let mut func = Function::with_name_signature(ExternalName::user(0, 0), sig);

src/debuginfo.rs

+19-41
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use crate::prelude::*;
22

3+
use crate::backend::WriteDebugInfo;
4+
35
use std::marker::PhantomData;
46

57
use syntax::source_map::FileName;
@@ -10,8 +12,6 @@ use gimli::write::{
1012
};
1113
use gimli::{Encoding, Format, LineEncoding, RunTimeEndian, SectionId};
1214

13-
use faerie::*;
14-
1515
fn target_endian(tcx: TyCtxt) -> RunTimeEndian {
1616
use rustc::ty::layout::Endian;
1717

@@ -56,31 +56,22 @@ fn line_program_add_file(
5656
}
5757

5858
#[derive(Clone)]
59-
struct DebugReloc {
60-
offset: u32,
61-
size: u8,
62-
name: DebugRelocName,
63-
addend: i64,
59+
pub struct DebugReloc {
60+
pub offset: u32,
61+
pub size: u8,
62+
pub name: DebugRelocName,
63+
pub addend: i64,
6464
}
6565

6666
#[derive(Clone)]
67-
enum DebugRelocName {
67+
pub enum DebugRelocName {
6868
Section(SectionId),
6969
Symbol(usize),
7070
}
7171

72-
impl DebugReloc {
73-
fn name<'a>(&self, ctx: &'a DebugContext) -> &'a str {
74-
match self.name {
75-
DebugRelocName::Section(id) => id.name(),
76-
DebugRelocName::Symbol(index) => ctx.symbols.get_index(index).unwrap(),
77-
}
78-
}
79-
}
80-
8172
pub struct DebugContext<'tcx> {
8273
endian: RunTimeEndian,
83-
symbols: indexmap::IndexSet<String>,
74+
symbols: indexmap::IndexSet<(String, FuncId)>,
8475

8576
dwarf: DwarfUnit,
8677
unit_range_list: RangeList,
@@ -177,7 +168,7 @@ impl<'tcx> DebugContext<'tcx> {
177168
);
178169
}
179170

180-
pub fn emit(&mut self, artifact: &mut Artifact) {
171+
pub fn emit<P: WriteDebugInfo>(&mut self, product: &mut P) {
181172
let unit_range_list_id = self.dwarf.unit.ranges.add(self.unit_range_list.clone());
182173
let root = self.dwarf.unit.root();
183174
let root = self.dwarf.unit.get_mut(root);
@@ -189,34 +180,20 @@ impl<'tcx> DebugContext<'tcx> {
189180
let mut sections = Sections::new(WriterRelocate::new(self));
190181
self.dwarf.write(&mut sections).unwrap();
191182

183+
let mut section_map = HashMap::new();
192184
let _: Result<()> = sections.for_each_mut(|id, section| {
193185
if !section.writer.slice().is_empty() {
194-
artifact
195-
.declare_with(
196-
id.name(),
197-
Decl::section(SectionKind::Debug),
198-
section.writer.take(),
199-
)
200-
.unwrap();
186+
let section_id = product.add_debug_section(id, section.writer.take());
187+
section_map.insert(id, section_id);
201188
}
202189
Ok(())
203190
});
204191

205192
let _: Result<()> = sections.for_each(|id, section| {
206-
for reloc in &section.relocs {
207-
artifact
208-
.link_with(
209-
faerie::Link {
210-
from: id.name(),
211-
to: reloc.name(self),
212-
at: u64::from(reloc.offset),
213-
},
214-
faerie::Reloc::Debug {
215-
size: reloc.size,
216-
addend: reloc.addend as i32,
217-
},
218-
)
219-
.expect("faerie relocation error");
193+
if let Some(section_id) = section_map.get(&id) {
194+
for reloc in &section.relocs {
195+
product.add_debug_reloc(&section_map, &self.symbols, section_id, reloc);
196+
}
220197
}
221198
Ok(())
222199
});
@@ -235,10 +212,11 @@ impl<'a, 'tcx> FunctionDebugContext<'a, 'tcx> {
235212
tcx: TyCtxt<'tcx>,
236213
debug_context: &'a mut DebugContext<'tcx>,
237214
mir: &Body,
215+
func_id: FuncId,
238216
name: &str,
239217
_sig: &Signature,
240218
) -> Self {
241-
let (symbol, _) = debug_context.symbols.insert_full(name.to_string());
219+
let (symbol, _) = debug_context.symbols.insert_full((name.to_string(), func_id));
242220

243221
// FIXME: add to appropriate scope intead of root
244222
let scope = debug_context.dwarf.unit.root();

src/metadata.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_data_structures::owning_ref::{self, OwningRef};
99
use rustc_data_structures::rustc_erase_owner;
1010
use rustc_target::spec::Target;
1111

12-
use crate::backend::Product;
12+
use crate::backend::WriteMetadata;
1313

1414
pub struct CraneliftMetadataLoader;
1515

@@ -53,7 +53,7 @@ impl MetadataLoader for CraneliftMetadataLoader {
5353
}
5454

5555
// Adapted from https://github.com/rust-lang/rust/blob/da573206f87b5510de4b0ee1a9c044127e409bd3/src/librustc_codegen_llvm/base.rs#L47-L112
56-
pub fn write_metadata<P: Product>(tcx: TyCtxt<'_>, product: &mut P) -> EncodedMetadata {
56+
pub fn write_metadata<P: WriteMetadata>(tcx: TyCtxt<'_>, product: &mut P) -> EncodedMetadata {
5757
use flate2::write::DeflateEncoder;
5858
use flate2::Compression;
5959
use std::io::Write;

0 commit comments

Comments
 (0)